758int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
760 Q_ASSERT(o == object);
765 if (intercept(c, _id, a))
768 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
769 if (id >= propOffset()) {
772 const QQmlPropertyData *propertyData = cache->property(_id);
773 if (!propertyData->isAlias()) {
776 QQmlEnginePrivate *ep = (m_ctxt.isNull() || m_ctxt->engine() ==
nullptr)
778 : QQmlEnginePrivate::get(m_ctxt->engine());
780 if (c == QMetaObject::ReadProperty) {
781 if (propertyData->isQList()) {
783 const QQmlPropertyData *propertyData = cache->property(_id);
784 const QMetaType propType = propertyData->propType();
786 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
787 if (!getListProperty(
788 id,
static_cast<QQmlListProperty<QObject> *>(a[0]))) {
791 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
793 QV4::Scope scope(m_engine);
794 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
795 switch (QV4::SequencePrototype::getRawContainer(
796 sequence, a[0], propType)) {
797 case QV4::SequencePrototype::Copied:
798 case QV4::SequencePrototype::WasEqual:
800 case QV4::SequencePrototype::TypeMismatch:
803 propType.destruct(a[0]);
804 propType.construct(a[0]);
808 qmlWarning(object) <<
"Cannot find member data";
811 const QV4::CompiledData::CommonType t
812 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
813 propertyData->propType());
815 case QV4::CompiledData::CommonType::Void:
817 case QV4::CompiledData::CommonType::Int:
818 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
820 case QV4::CompiledData::CommonType::Bool:
821 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
823 case QV4::CompiledData::CommonType::Real:
824 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
826 case QV4::CompiledData::CommonType::String:
827 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
829 case QV4::CompiledData::CommonType::Url:
830 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
832 case QV4::CompiledData::CommonType::Date:
833 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
835 case QV4::CompiledData::CommonType::DateTime:
836 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
838 case QV4::CompiledData::CommonType::RegExp:
839#if QT_CONFIG(regularexpression)
840 *
reinterpret_cast<QRegularExpression *>(a[0])
841 = readPropertyAsRegularExpression(id);
844 case QV4::CompiledData::CommonType::Rect:
845 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
847 case QV4::CompiledData::CommonType::Size:
848 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
850 case QV4::CompiledData::CommonType::Point:
851 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
853 case QV4::CompiledData::CommonType::Time:
854 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
856 case QV4::CompiledData::CommonType::Var:
858 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
862 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
865 case QV4::CompiledData::CommonType::Invalid:
866 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
867 QV4::Scope scope(m_engine);
868 QV4::ScopedValue sv(scope, *(md->data() + id));
871 const QQmlPropertyData *propertyData = cache->property(_id);
873 if (propertyData->isQObject()) {
874 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
875 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
877 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
879 const QMetaType propType = propertyData->propType();
880 const void *data =
nullptr;
881 if (
const auto *v = sv->as<QV4::VariantObject>()) {
882 const QVariant &variant = v->d()->data();
883 if (variant.metaType() == propType)
884 data = variant.constData();
886 propType.destruct(a[0]);
887 propType.construct(a[0], data);
890 qmlWarning(object) <<
"Cannot find member data";
894 }
else if (c == QMetaObject::WriteProperty) {
895 bool needActivate =
false;
897 if (propertyData->isQList()) {
898 const QMetaType propType = propertyData->propType();
900 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
902 QQmlListProperty<QObject> listProp;
903 if (!getListProperty(id, &listProp))
906 QQmlListProperty<QObject> *input
907 =
static_cast<QQmlListProperty<QObject> *>(a[0]);
911 if (listProp.count(&listProp) != input->count(input)) {
914 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
915 if (listProp.at(&listProp, i) == input->at(input, i))
926 QQmlVMEMetaObject::list_clear_nosignal(&listProp);
927 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
928 QQmlVMEMetaObject::list_append_nosignal(
929 &listProp, input->at(input, i));
932 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
934 QV4::Scope scope(m_engine);
935 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
936 switch (QV4::SequencePrototype::setRawContainer(
937 sequence, a[0], propType)) {
938 case QV4::SequencePrototype::Copied:
941 case QV4::SequencePrototype::WasEqual:
943 case QV4::SequencePrototype::TypeMismatch: {
944 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
945 type.isSequentialContainer()) {
946 sequence = QV4::SequencePrototype::fromData(
947 m_engine, propType, type.listMetaSequence(), a[0]);
948 }
else if (QMetaSequence::Iterable iterable;
951 QMetaType::fromType<QMetaSequence::Iterable>(),
953 sequence = QV4::SequencePrototype::fromData(
954 m_engine, propType, iterable.metaContainer(), a[0]);
956 sequence = QV4::Encode::undefined();
958 md->set(m_engine, id, sequence);
959 if (sequence->isUndefined()) {
961 <<
"Could not create a QML sequence object for "
969 qmlWarning(object) <<
"Cannot find member data";
972 const QV4::CompiledData::CommonType t
973 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
974 propertyData->propType());
976 case QV4::CompiledData::CommonType::Void:
978 case QV4::CompiledData::CommonType::Int:
979 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
980 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
982 case QV4::CompiledData::CommonType::Bool:
983 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
984 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
986 case QV4::CompiledData::CommonType::Real:
987 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
988 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
990 case QV4::CompiledData::CommonType::String:
991 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
992 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
994 case QV4::CompiledData::CommonType::Url:
995 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
996 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
998 case QV4::CompiledData::CommonType::Date:
999 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
1000 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
1002 case QV4::CompiledData::CommonType::DateTime:
1003 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
1004 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
1006 case QV4::CompiledData::CommonType::RegExp:
1007#if QT_CONFIG(regularexpression)
1008 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
1009 != readPropertyAsRegularExpression(id);
1010 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
1013 case QV4::CompiledData::CommonType::Rect:
1014 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
1015 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
1017 case QV4::CompiledData::CommonType::Size:
1018 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
1019 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
1021 case QV4::CompiledData::CommonType::Point:
1022 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
1023 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
1025 case QV4::CompiledData::CommonType::Time:
1026 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1027 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1029 case QV4::CompiledData::CommonType::Var:
1031 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1033 case QV4::CompiledData::CommonType::Invalid:
1034 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1035 QV4::Scope scope(m_engine);
1036 QV4::ScopedValue sv(scope, *(md->data() + id));
1039 const QQmlPropertyData *propertyData = cache->property(_id);
1041 if (propertyData->isQObject()) {
1042 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1043 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1044 needActivate = wrap->object() != arg;
1045 else if (arg !=
nullptr || !sv->isNull())
1046 needActivate =
true;
1048 writeProperty(id, arg);
1050 const QMetaType propType = propertyData->propType();
1051 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1052 QVariant &variant = v->d()->data();
1053 if (variant.metaType() != propType) {
1054 needActivate =
true;
1055 variant = QVariant(propType, a[0]);
1056 }
else if (!propType.equals(variant.constData(), a[0])) {
1057 needActivate =
true;
1058 propType.destruct(variant.data());
1059 propType.construct(variant.data(), a[0]);
1062 needActivate =
true;
1063 md->set(m_engine, id, m_engine->newVariantObject(
1068 qmlWarning(object) <<
"Cannot find member data";
1074 activate(object, id,
nullptr);
1082 if (id < aliasCount()) {
1083 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1084 if (!compiledObject)
1087 const QQmlPropertyData *aliasProperty = cache->property(aliasOffset() + id);
1088 if (c == QMetaObject::ReadProperty && aliasProperty && aliasProperty->isQObject())
1089 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1091 if (m_ctxt.isNull())
1094 QObject *target = m_ctxt->idValue(
1095 aliasProperty ? aliasProperty->aliasTargetObjectId() : -1);
1099 connectAlias(compiledObject, id);
1101 const int targetPropertyIndex = aliasProperty ? aliasProperty->aliasTarget() : -1;
1103 if (targetPropertyIndex == -1) {
1104 *
reinterpret_cast<QObject **>(a[0]) = target;
1108 QQmlData *targetDData = QQmlData::get(target,
false);
1112 QQmlPropertyIndex encodedIndex
1113 = QQmlPropertyIndex::fromEncoded(targetPropertyIndex);
1114 int coreIndex = encodedIndex.coreIndex();
1115 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1117 const auto removePendingBinding
1118 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1120 if (c == QMetaObject::WriteProperty) {
1121 int flags = *
reinterpret_cast<
int*>(a[3]);
1122 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1123 QQmlData *targetData = QQmlData::get(target);
1124 if (targetData && targetData->hasBindingBit(coreIndex)) {
1125 if (QQmlPropertyPrivate::removeBinding(
1126 target, encodedIndex, QQmlPropertyPrivate::None)) {
1127 targetData->clearBindingBit(coreIndex);
1134 if (valueTypePropertyIndex != -1) {
1135 if (!targetDData->propertyCache)
1137 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1139 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1140 m_ctxt->engine(), pd->propType());
1144 if (c == QMetaObject::BindableProperty)
1145 return QMetaObject::metacall(target, c, coreIndex, a);
1147 removePendingBinding(target, coreIndex, encodedIndex);
1148 valueType->read(target, coreIndex);
1149 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1151 if (c == QMetaObject::WriteProperty)
1152 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1153 valueTypePropertyIndex);
1158 void *argv[1] = { &target };
1159 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1160 removePendingBinding(
1161 target, valueTypePropertyIndex,
1162 QQmlPropertyIndex(valueTypePropertyIndex));
1163 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1167 removePendingBinding(target, coreIndex, encodedIndex);
1168 return QMetaObject::metacall(target, c, coreIndex, a);
1176 }
else if(c == QMetaObject::InvokeMetaMethod) {
1178 if (id >= signalOffset()) {
1180 id -= signalOffset();
1181 if (id < signalCount()) {
1182 activate(object, id, a);
1186 id -= signalCount();
1187 if (id < methodCount()) {
1188 QQmlEngine *engine = m_ctxt->engine();
1192 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1193 QV4::ExecutionEngine *v4 = engine->handle();
1194 ep->referenceScarceResources();
1195 QV4::Scope scope(v4);
1198 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1207 "Exception occurred during compilation of function: ")
1208 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1213 auto methodData = cache->method(_id);
1214 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1216 if (arguments && arguments->names) {
1217 const quint32 parameterCount = arguments->names->size();
1218 Q_ASSERT(parameterCount == function->formalParameterCount());
1219 function->call(object, a, arguments->types, parameterCount);
1221 Q_ASSERT(function->formalParameterCount() == 0);
1222 const QMetaType returnType = methodData->propType();
1223 function->call(object, a, &returnType, 0);
1226 if (scope.hasException()) {
1227 QQmlError error = scope.engine->catchExceptionAsQmlError();
1228 if (error.isValid())
1232 ep->dereferenceScarceResources();
1240 return parent.asT1()->metaCall(object, c, _id, a);
1242 return object->qt_metacall(c, _id, a);