From fe38b5c906de656c3e1a9491e9382e002d886f11 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Fri, 19 Feb 2021 16:50:38 +0100 Subject: Engine: Cleanup method argument passing Instead of arguments around as a pointer to [argc, metaTypeId1, metaTypeId12, ...] pass argc and a pointer to [QMetaType1, QMetaType2] around. Moreover, make use of the fact that we now carry the metatype instead of only the id in a few places, to avoid id -> metatype lookups. Task-number: QTBUG-82931 Change-Id: Ib00e4d793727f85f3358a8162d1aac972daab3d3 Reviewed-by: Ulf Hermann --- src/qml/jsruntime/qv4engine.cpp | 8 +- src/qml/jsruntime/qv4engine_p.h | 2 +- src/qml/jsruntime/qv4jscall.cpp | 7 +- src/qml/jsruntime/qv4jscall_p.h | 4 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 90 +++++++++++----------- src/qml/qml/qqmlboundsignal.cpp | 6 +- src/qml/qml/qqmlengine.cpp | 4 +- src/qml/qml/qqmlengine_p.h | 2 +- src/qml/qml/qqmlmetaobject.cpp | 16 ++-- src/qml/qml/qqmlmetaobject_p.h | 18 ++++- .../qmlcompiler_manual/tst_qmlcompiler_manual.cpp | 27 ++++--- tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 10 +-- 12 files changed, 101 insertions(+), 93 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 6035878fcf..d7bc5a46cf 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2064,8 +2064,8 @@ bool ExecutionEngine::diskCacheEnabled() const } ReturnedValue ExecutionEngine::callInContext(Function *function, QObject *self, - QQmlRefPointer ctxtdata, void **args, - int *types) + QQmlRefPointer ctxtdata, int argc, void **args, + QMetaType *types) { QV4::Scope scope(this); ExecutionContext *ctx = currentStackFrame ? currentContext() : scriptContext(); @@ -2079,8 +2079,8 @@ ReturnedValue ExecutionEngine::callInContext(Function *function, QObject *self, return Encode::undefined(); // use JSCallData to pass arguments into the function call - QV4::JSCallData jsCall(scope, types[0]); - QV4::populateJSCallArguments(this, jsCall, args, types); + QV4::JSCallData jsCall(scope, argc); + QV4::populateJSCallArguments(this, jsCall, argc, args, types); QV4::CallData *callData = jsCall->callData(); return function->call(selfValue, callData->argValues(), callData->argc(), diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index d91f7bf4a3..6c3d2d4436 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -744,7 +744,7 @@ public: bool diskCacheEnabled() const; ReturnedValue callInContext(Function *function, QObject *self, - QQmlRefPointer ctxtdata, void **args, int *types); + QQmlRefPointer ctxtdata, int argc, void **args, QMetaType *types); private: #if QT_CONFIG(qml_debug) diff --git a/src/qml/jsruntime/qv4jscall.cpp b/src/qml/jsruntime/qv4jscall.cpp index 8cd656ae2e..191436bd69 100644 --- a/src/qml/jsruntime/qv4jscall.cpp +++ b/src/qml/jsruntime/qv4jscall.cpp @@ -50,11 +50,10 @@ QT_BEGIN_NAMESPACE information provided by \a types */ void QV4::populateJSCallArguments(ExecutionEngine *v4, JSCallData &jsCall, - void **args, int *types) + int argc, void **args, const QMetaType *types) { - const int argCount = types ? types[0] : 0; - for (int ii = 0; ii < argCount; ++ii) { - auto type = QMetaType(types[ii + 1]); + for (int ii = 0; ii < argc; ++ii) { + auto type = QMetaType(types[ii]); jsCall.args[ii] = v4->metaTypeToJS(type, args[ii + 1]); } } diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index e0b47c76e3..66ff1e7c3b 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -112,8 +112,8 @@ ReturnedValue FunctionObject::call(const JSCallData &data) const return call(data.thisObject, data.args, data.argc); } -void populateJSCallArguments(ExecutionEngine *v4, JSCallData &jsCall, - void **args, int *types); +void populateJSCallArguments(ExecutionEngine *v4, JSCallData &jsCall, int argc, + void **args, const QMetaType *types); struct ScopedStackFrame { Scope &scope; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 6de528666f..86d37bb5ec 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -999,9 +999,9 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase break; QQmlMetaObject::ArgTypeStorage storage; - int *argsTypes = QQmlMetaObject(r).methodParameterTypes(This->signalIndex, &storage, nullptr); + QQmlMetaObject(r).methodParameterTypes(This->signalIndex, &storage, nullptr); - int argCount = argsTypes ? argsTypes[0]:0; + int argCount = storage.size(); QV4::Scope scope(v4); QV4::ScopedFunctionObject f(scope, This->function.value()); @@ -1009,11 +1009,11 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase QV4::JSCallData jsCallData(scope, argCount); *jsCallData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value(); for (int ii = 0; ii < argCount; ++ii) { - int type = argsTypes[ii + 1]; - if (type == qMetaTypeId()) { + QMetaType type = storage[ii]; + if (type == QMetaType::fromType()) { jsCallData->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1])); } else { - jsCallData->args[ii] = v4->fromVariant(QVariant(QMetaType(type), metaArgs[ii + 1])); + jsCallData->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1])); } } @@ -1297,8 +1297,8 @@ struct CallArgument { inline ~CallArgument(); inline void *dataPtr(); - inline void initAsType(int type); - inline bool fromValue(int type, ExecutionEngine *, const QV4::Value &); + inline void initAsType(QMetaType type); + inline bool fromValue(QMetaType type, ExecutionEngine *, const QV4::Value &); inline ReturnedValue toValue(ExecutionEngine *); private: @@ -1350,8 +1350,8 @@ private: }; } -static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, int returnType, int argCount, - int *argTypes, QV4::ExecutionEngine *engine, QV4::CallData *callArgs, +static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, QMetaType returnType, int argCount, + const QMetaType *argTypes, QV4::ExecutionEngine *engine, QV4::CallData *callArgs, QMetaObject::Call callType = QMetaObject::InvokeMetaMethod) { if (argCount > 0) { @@ -1390,7 +1390,7 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index return args[0].toValue(engine); - } else if (returnType != QMetaType::Void) { + } else if (returnType != QMetaType::fromType()) { CallArgument arg; arg.initAsType(returnType); @@ -1416,8 +1416,9 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index The conversion table is copied out of the \l QScript::callQtMethod() function. */ -static int MatchScore(const QV4::Value &actual, int conversionType) +static int MatchScore(const QV4::Value &actual, QMetaType conversionMetaType) { + const int conversionType = conversionMetaType.id(); if (actual.isNumber()) { switch (conversionType) { case QMetaType::Double: @@ -1513,8 +1514,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) case QMetaType::QJsonValue: return 0; default: { - const char *typeName = QMetaType(conversionType).name(); - if (typeName && typeName[strlen(typeName) - 1] == '*') + if (conversionMetaType.flags().testFlag(QMetaType::IsPointer)) return 0; else return 10; @@ -1524,7 +1524,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) if (obj->as()) { if (conversionType == qMetaTypeId()) return 0; - if (obj->engine()->toVariant(actual, -1).userType() == conversionType) + if (obj->engine()->toVariant(actual, -1).metaType() == conversionMetaType) return 0; else return 10; @@ -1550,7 +1550,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) const QVariant v = obj->engine()->toVariant(actual, -1); if (v.userType() == conversionType) return 0; - else if (v.canConvert(QMetaType(conversionType))) + else if (v.canConvert(conversionMetaType)) return 5; return 10; } else if (conversionType == QMetaType::QJsonObject) { @@ -1582,9 +1582,9 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ { QByteArray unknownTypeError; - int returnType = object.methodReturnType(data, &unknownTypeError).id(); + QMetaType returnType = object.methodReturnType(data, &unknownTypeError); - if (returnType == QMetaType::UnknownType) { + if (!returnType.isValid()) { return engine->throwError(QLatin1String("Unknown method return type: ") + QLatin1String(unknownTypeError)); } @@ -1620,31 +1620,31 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ if (data.hasArguments()) { - int *args = nullptr; QQmlMetaObject::ArgTypeStorage storage; + bool ok = false; if (data.isConstructor()) - args = object.constructorParameterTypes(data.coreIndex(), &storage, &unknownTypeError); + ok = object.constructorParameterTypes(data.coreIndex(), &storage, &unknownTypeError); else - args = object.methodParameterTypes(data.coreIndex(), &storage, &unknownTypeError); + ok = object.methodParameterTypes(data.coreIndex(), &storage, &unknownTypeError); - if (!args) { + if (!ok) { return engine->throwError(QLatin1String("Unknown method parameter type: ") + QLatin1String(unknownTypeError)); } - if (args[0] > callArgs->argc()) { + if (storage.size() > callArgs->argc()) { QString error = QLatin1String("Insufficient arguments"); return engine->throwError(error); } - if (args[0] < definedArgumentCount) { - if (!handleTooManyArguments(args[0])) + if (storage.size() < definedArgumentCount) { + if (!handleTooManyArguments(storage.size())) return Encode::undefined(); } - return CallMethod(object, data.coreIndex(), returnType, args[0], args + 1, engine, callArgs, callType); + return CallMethod(object, data.coreIndex(), returnType, storage.size(), storage.constData(), engine, callArgs, callType); } else { if (definedArgumentCount > 0 && !handleTooManyArguments(0)) @@ -1685,19 +1685,15 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const const QQmlPropertyData &attempt = methods[i]; QQmlMetaObject::ArgTypeStorage storage; int methodArgumentCount = 0; - int *methodArgTypes = nullptr; if (attempt.hasArguments()) { - int *args = [&]() { - if (attempt.isConstructor()) - return object.constructorParameterTypes(attempt.coreIndex(), &storage, nullptr); - else - return object.methodParameterTypes(attempt.coreIndex(), &storage, nullptr); - }(); - if (!args) // Must be an unknown argument - continue; - - methodArgumentCount = args[0]; - methodArgTypes = args + 1; + if (attempt.isConstructor()) { + if (!object.constructorParameterTypes(attempt.coreIndex(), &storage, nullptr)) + continue; + } else { + if (!object.methodParameterTypes(attempt.coreIndex(), &storage, nullptr)) + continue; + } + methodArgumentCount = storage.size(); } if (methodArgumentCount > argumentCount) @@ -1710,7 +1706,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const int methodMatchScore = 0; for (int ii = 0; ii < methodArgumentCount; ++ii) { methodMatchScore += MatchScore((v = QV4::Value::fromStaticValue(callArgs->args[ii])), - methodArgTypes[ii]); + storage[ii]); } if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) { @@ -1796,9 +1792,10 @@ void *CallArgument::dataPtr() return nullptr; } -void CallArgument::initAsType(int callType) +void CallArgument::initAsType(QMetaType metaType) { if (type != 0) { cleanup(); type = 0; } + const int callType = metaType.id(); if (callType == QMetaType::UnknownType || callType == QMetaType::Void) return; if (callType == qMetaTypeId()) { @@ -1833,7 +1830,7 @@ void CallArgument::initAsType(int callType) jsonValuePtr = new (&allocData) QJsonValue(); } else { type = -1; - qvariantPtr = new (&allocData) QVariant(QMetaType(callType), (void *)nullptr); + qvariantPtr = new (&allocData) QVariant(metaType, (void *)nullptr); } } @@ -1852,7 +1849,7 @@ void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M } #endif -bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value) +bool CallArgument::fromValue(QMetaType metaType, QV4::ExecutionEngine *engine, const QV4::Value &value) { if (type != 0) { cleanup(); @@ -1861,6 +1858,7 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q QV4::Scope scope(engine); + const int callType = metaType.id(); bool queryEngine = false; if (callType == qMetaTypeId()) { qjsValuePtr = new (&allocData) QJSValue; @@ -1970,11 +1968,11 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q #endif } #endif - } else if (QMetaType(callType).flags() + } else if (metaType.flags() & (QMetaType::PointerToQObject | QMetaType::PointerToGadget)) { // You can assign null or undefined to any pointer. The result is a nullptr. if (value.isNull() || value.isUndefined()) { - qvariantPtr = new (&allocData) QVariant(QMetaType(callType), nullptr); + qvariantPtr = new (&allocData) QVariant(metaType, nullptr); type = callType; } else { queryEngine = true; @@ -2002,15 +2000,15 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q QObject *obj = ep->toQObject(v); if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) { - *qvariantPtr = QVariant(QMetaType(callType), nullptr); + *qvariantPtr = QVariant(metaType, nullptr); return false; } - *qvariantPtr = QVariant(QMetaType(callType), &obj); + *qvariantPtr = QVariant(metaType, &obj); return true; } - *qvariantPtr = QVariant(QMetaType(callType), (void *)nullptr); + *qvariantPtr = QVariant(metaType, (void *)nullptr); return false; } } diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 97ccb1969b..9e1e056381 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -190,11 +190,11 @@ void QQmlBoundSignalExpression::evaluate(void **a) QQmlMetaObject::ArgTypeStorage storage; //TODO: lookup via signal index rather than method index as an optimization int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex(); - int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, nullptr); - int argCount = argsTypes ? *argsTypes : 0; + bool ok = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, nullptr); + const int argCount = ok ? storage.size() : 0; QV4::JSCallData jsCall(scope, argCount); - populateJSCallArguments(v4, jsCall, a, argsTypes); + populateJSCallArguments(v4, jsCall, argCount, a, storage.constData()); QQmlJavaScriptExpression::evaluate(jsCall.callData(), nullptr); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index e8604060b9..ba9de0ab61 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -2289,7 +2289,7 @@ bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const } QJSValue QQmlEnginePrivate::executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, - QObject *thisObject, void **args, int *types) + QObject *thisObject, int argc, void **args, QMetaType *types) { Q_Q(QQmlEngine); if (const auto unit = typeLoader.getType(url)->compilationUnit()) { @@ -2307,7 +2307,7 @@ QJSValue QQmlEnginePrivate::executeRuntimeFunction(const QUrl &url, qsizetype fu ctx = q->rootContext(); return QJSValuePrivate::fromReturnedValue( q->handle()->callInContext(unit->runtimeFunctions[functionIndex], thisObject, - QQmlContextData::get(ctx), args, types)); + QQmlContextData::get(ctx), argc, args, types)); } return QJSValue(); } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 4f1c5f26dd..df78149b0b 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -301,7 +301,7 @@ public: } QJSValue executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, QObject *thisObject, - void **args = nullptr, int *types = nullptr); + int arcg=0, void **args = nullptr, QMetaType *types = nullptr); private: class SingletonInstances : private QHash diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp index 5cafa3f74d..585920a99f 100644 --- a/src/qml/qml/qqmlmetaobject.cpp +++ b/src/qml/qml/qqmlmetaobject.cpp @@ -114,7 +114,7 @@ QMetaType QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteAr return QMetaType(); } -int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage, +bool QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage, QByteArray *unknownTypeError) const { Q_ASSERT(_m && index >= 0); @@ -123,21 +123,20 @@ int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage, return methodParameterTypes(m, argStorage, unknownTypeError); } -int *QQmlMetaObject::constructorParameterTypes(int index, ArgTypeStorage *dummy, +bool QQmlMetaObject::constructorParameterTypes(int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const { QMetaMethod m = _m->constructor(index); return methodParameterTypes(m, dummy, unknownTypeError); } -int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *argStorage, +bool QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *argStorage, QByteArray *unknownTypeError) const { Q_ASSERT(argStorage); int argc = m.parameterCount(); - argStorage->resize(argc + 1); - argStorage->operator[](0) = argc; + argStorage->resize(argc); for (int ii = 0; ii < argc; ++ii) { QMetaType type = m.parameterMetaType(ii); // we treat enumerations as int @@ -146,12 +145,11 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage * if (!type.isValid()) { if (unknownTypeError) *unknownTypeError = m.parameterTypeName(ii); - return nullptr; + return false; } - argStorage->operator[](ii + 1) = type.id(); + argStorage->operator[](ii) = type; } - - return argStorage->data(); + return true; } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlmetaobject_p.h b/src/qml/qml/qqmlmetaobject_p.h index e5b8fc0148..0cb440b38c 100644 --- a/src/qml/qml/qqmlmetaobject_p.h +++ b/src/qml/qml/qqmlmetaobject_p.h @@ -72,7 +72,7 @@ class QQmlPropertyData; class Q_QML_EXPORT QQmlMetaObject { public: - typedef QVarLengthArray ArgTypeStorage; + typedef QVarLengthArray ArgTypeStorage; inline QQmlMetaObject() = default; inline QQmlMetaObject(const QObject *); @@ -90,9 +90,19 @@ public: inline const QMetaObject *metaObject() const; QMetaType methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const; - int *methodParameterTypes(int index, ArgTypeStorage *argStorage, + /*! + \internal + Returns false if one of the types is unknown. Otherwise, fills \a argstorage with the + metatypes of the function. + */ + bool methodParameterTypes(int index, ArgTypeStorage *argStorage, QByteArray *unknownTypeError) const; - int *constructorParameterTypes(int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const; + /*! + \internal + Returns false if one of the types is unknown. Otherwise, fills \a argstorage with the + metatypes of the function. + */ + bool constructorParameterTypes(int index, ArgTypeStorage *dummy, QByteArray *unknownTypeError) const; static bool canConvert(const QQmlMetaObject &from, const QQmlMetaObject &to); @@ -103,7 +113,7 @@ public: protected: const QMetaObject *_m = nullptr; - int *methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage, + bool methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage, QByteArray *unknownTypeError) const; }; diff --git a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp index b3b452a4d1..3a754a28ca 100644 --- a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp +++ b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp @@ -100,14 +100,14 @@ static constexpr int PROPERTY_RETURNING_FUNCTION_F_BINDING = 0; // test utility function for type erasure. the "real" code would be // auto-generated by the compiler template -static void typeEraseArguments(std::array &a, std::array &t, +static void typeEraseArguments(std::array &a, std::array &t, IOArgs &&... args) { a = { /* return type */ nullptr, /* rest */ const_cast( reinterpret_cast(std::addressof(std::forward(args))))... }; - t = { /* arg count */ sizeof...(IOArgs), - /* rest */ QMetaTypeId2>::qt_metatype_id()... }; + t = { + /* types */ QMetaType::fromType>()... }; } class HelloWorld : public QObject @@ -229,13 +229,14 @@ public slots: void onSignal2(QString x, int y) { - std::array a {}; - std::array t {}; + constexpr int argc = 2; + std::array a {}; + std::array t {}; typeEraseArguments(a, t, x, y); QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); const qsizetype index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL2; - e->executeRuntimeFunction(url, index, this, a.data(), t.data()); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); } public: @@ -255,13 +256,14 @@ public: void qmlEmitSignal2WithArgs(QString x, int y) { - std::array a {}; - std::array t {}; + constexpr int argc = 2; + std::array a {}; + std::array t {}; typeEraseArguments(a, t, x, y); QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2_WITH_ARGS; - e->executeRuntimeFunction(url, index, this, a.data(), t.data()); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); } }; @@ -361,13 +363,14 @@ public: void func2(QString x) { - std::array a {}; - std::array t {}; + constexpr int argc = 1; + std::array a {}; + std::array t {}; typeEraseArguments(a, t, x); QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); const auto index = FunctionIndices::JS_FUNCTIONS_FUNC2; - e->executeRuntimeFunction(url, index, this, a.data(), t.data()); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); } bool func3() diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index 6ff6d7fbfd..68d8d288fa 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -1252,9 +1252,9 @@ void tst_qqmlengine::executeRuntimeFunction() // squareValue(): int x = 5; void *a0[] = { nullptr, const_cast(reinterpret_cast(std::addressof(x))) }; - int t0[] = { 1, QMetaTypeId2::qt_metatype_id() }; + QMetaType t0[] = { QMetaType::fromType() }; const int squared = - qjsvalue_cast(priv->executeRuntimeFunction(url, 1, dummy.get(), a0, t0)); + qjsvalue_cast(priv->executeRuntimeFunction(url, 1, dummy.get(), 1, a0, t0)); QCOMPARE(squared, x * x); // concatenate(): @@ -1263,10 +1263,10 @@ void tst_qqmlengine::executeRuntimeFunction() void *a1[] = { nullptr, const_cast(reinterpret_cast(std::addressof(str1))), const_cast(reinterpret_cast(std::addressof(str2))) }; - int t1[] = { 2, QMetaTypeId2::qt_metatype_id(), - QMetaTypeId2::qt_metatype_id() }; + QMetaType t1[] = { QMetaType::fromType(), + QMetaType::fromType() }; QString concatenated = - qjsvalue_cast(priv->executeRuntimeFunction(url, 2, dummy.get(), a1, t1)); + qjsvalue_cast(priv->executeRuntimeFunction(url, 2, dummy.get(), 2, a1, t1)); QCOMPARE(concatenated, str1 + str2); } -- cgit v1.2.3