7#include <private/qjsvalue_p.h>
8#include <private/qjsmanagedvalue_p.h>
10#include <private/qqmlbinding_p.h>
11#include <private/qqmlbuiltinfunctions_p.h>
12#include <private/qqmlengine_p.h>
13#include <private/qqmlobjectorgadget_p.h>
14#include <private/qqmlpropertybinding_p.h>
15#include <private/qqmlscriptstring_p.h>
16#include <private/qqmlsignalnames_p.h>
17#include <private/qqmltypewrapper_p.h>
18#include <private/qqmlvaluetypewrapper_p.h>
19#include <private/qqmlvmemetaobject_p.h>
21#include <private/qv4arraybuffer_p.h>
22#include <private/qv4arrayobject_p.h>
23#include <private/qv4compileddata_p.h>
24#include <private/qv4dateobject_p.h>
25#include <private/qv4functionobject_p.h>
26#include <private/qv4identifiertable_p.h>
27#include <private/qv4jscall_p.h>
28#include <private/qv4jsonobject_p.h>
29#include <private/qv4lookup_p.h>
30#include <private/qv4mm_p.h>
31#include <private/qv4regexpobject_p.h>
32#include <private/qv4runtime_p.h>
33#include <private/qv4scopedvalue_p.h>
34#include <private/qv4sequenceobject_p.h>
35#include <private/qv4variantobject_p.h>
37#include <QtCore/qjsonarray.h>
38#include <QtCore/qjsonobject.h>
39#include <QtCore/qjsonvalue.h>
40#include <QtCore/qloggingcategory.h>
41#include <QtCore/qmetaobject.h>
42#include <QtCore/qqueue.h>
43#include <QtCore/qtimer.h>
44#include <QtCore/qtypes.h>
45#include <QtCore/qvarlengtharray.h>
49#if QT_CONFIG(qml_itemmodel)
50#include <QtCore/qabstractitemmodel.h>
56Q_STATIC_LOGGING_CATEGORY(lcObjectConnect,
"qt.qml.object.connect", QtWarningMsg)
57Q_STATIC_LOGGING_CATEGORY(lcOverloadResolution,
"qt.qml.overloadresolution", QtWarningMsg)
58Q_STATIC_LOGGING_CATEGORY(lcMethodBehavior,
"qt.qml.method.behavior")
59Q_STATIC_LOGGING_CATEGORY(lcSignalHandler,
"qt.qml.signalhandler")
63QT_WARNING_DISABLE_GCC(
"-Wstrict-aliasing")
65using namespace Qt::StringLiterals;
84 if (value.isObject()) {
85 ExecutionEngine *v4 = value.as<Object>()->engine();
87 ScopedFunctionObject function(scope, value);
89 return QObjectMethod::extractQtMethod(function);
91 Scoped<QmlSignalHandler> handler(scope, value);
93 return std::make_pair(handler->object(), handler->signalIndex());
96 return std::make_pair((QObject *)
nullptr, -1);
103 Heap::ReferenceObject::Flags flags = Heap::ReferenceObject::NoFlag;
104 if (CppStackFrame *stackFrame = v4->currentStackFrame) {
105 if (stackFrame->v4Function->executableCompilationUnit()->valueTypesAreCopied())
106 flags |= Heap::ReferenceObject::EnforcesLocation;
109 if (property.isWritable())
110 flags |= Heap::ReferenceObject::CanWriteBack;
221#if QT_CONFIG(regularexpression)
291 qWarning(
"QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
421 ExecutionEngine *v4, String *name,
const QQmlRefPointer<QQmlContextData> &qmlContext,
422 QObject *qobj,
bool *hasProperty =
nullptr)
424 if (!qmlContext || !qmlContext->imports())
425 return OptionalReturnedValue();
430 if (QQmlTypeLoader *typeLoader = v4->typeLoader()) {
431 QQmlTypeNameCache::Result r = qmlContext->imports()->query(name, typeLoader);
434 return OptionalReturnedValue();
436 if (r.scriptIndex != -1) {
437 return OptionalReturnedValue(Encode::undefined());
438 }
else if (r.type.isValid()) {
439 return OptionalReturnedValue(
440 QQmlTypeWrapper::create(v4, qobj,r.type, Heap::QQmlTypeWrapper::ExcludeEnums));
441 }
else if (r.importNamespace) {
442 return OptionalReturnedValue(QQmlTypeWrapper::create(
443 v4, qobj, qmlContext->imports(), r.importNamespace,
444 Heap::QQmlTypeWrapper::ExcludeEnums));
446 Q_UNREACHABLE_RETURN(OptionalReturnedValue());
448 return OptionalReturnedValue();
585
586
587
588
589
590
591
592
593
594
595
596
702 "Overwriting binding on %s::%s at %s:%d that was initially bound at %s",
711 "Overwriting binding on %s::%s at %s:%d",
730#define PROPERTY_STORE(cpptype, value)
734 void *argv[] = { &o, 0
, &status, &flags };
735 QMetaObject::metacall(object, QMetaObject::WriteProperty, property->coreIndex(), argv);
746 void *
a[] = {
nullptr };
1027 PropertyKey next(
const Object *o, Property *pd =
nullptr, PropertyAttributes *attrs =
nullptr)
override;
1030 QSet<QByteArray> m_alreadySeen;
1036 static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal(
"destroyed(QObject*)");
1037 static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal(
"destroyed()");
1038 static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot(
"deleteLater()");
1040 const QObjectWrapper *that =
static_cast<
const QObjectWrapper*>(o);
1042 QObject *thatObject = that->d()->object();
1043 if (thatObject && !QQmlData::wasDeleted(thatObject)) {
1044 const QMetaObject *mo = thatObject->metaObject();
1046 const bool preventDestruction = mo->superClass() || mo == &QObject::staticMetaObject;
1047 const int propertyCount = mo->propertyCount();
1049 ExecutionEngine *thatEngine = that->engine();
1050 Scope scope(thatEngine);
1052 ScopedString propName(scope, thatEngine->newString(QString::fromUtf8(property.name())));
1058 local.load(property);
1059 pd->value = that->getProperty(
1060 thatEngine, that->d(), thatObject, &local,
1061 QObjectWrapper::AttachMethods);
1063 return propName->toPropertyKey();
1065 const int methodCount = mo->methodCount();
1069 const QMetaMethod method = mo->method(index);
1071 if (method.access() == QMetaMethod::Private || (preventDestruction && (index == deleteLaterIdx || index == destroyedIdx1 || index == destroyedIdx2)))
1074 if (m_alreadySeen.contains(method.name()))
1077 m_alreadySeen.insert(method.name());
1078 ExecutionEngine *thatEngine = that->engine();
1079 Scope scope(thatEngine);
1080 ScopedString methodName(scope, thatEngine->newString(QString::fromUtf8(method.name())));
1086 pd->value = that->getProperty(
1087 thatEngine, that->d(), thatObject, &local,
1088 QObjectWrapper::AttachMethods);
1090 return methodName->toPropertyKey();
1094 return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
1230 static void impl(
int which, QSlotObjectBase *this_, QObject *receiver,
void **metaArgs,
bool *ret)
1238 if (QQmlData::wasDeleted(receiver))
1242 ExecutionEngine *v4 = This->function.engine();
1249 QQmlMetaObject::ArgTypeStorage<9> storage;
1250 QQmlMetaObject::methodParameterTypes(This->signal, &storage,
nullptr);
1252 const qsizetype argCount = std::min(storage.size(), This->maxNumArguments);
1255 ScopedFunctionObject f(scope, This->function.value());
1257 JSCallArguments jsCallData(scope, argCount);
1258 *jsCallData.thisObject = This->thisObject.isUndefined()
1259 ? v4->globalObject->asReturnedValue()
1260 : This->thisObject.value();
1261 for (qsizetype ii = 0; ii < argCount; ++ii) {
1262 QMetaType type = storage[ii];
1263 if (type == QMetaType::fromType<QVariant>()) {
1264 jsCallData.args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
1266 jsCallData.args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
1270 f->call(jsCallData);
1271 if (scope.hasException()) {
1272 QQmlError error = v4->catchExceptionAsQmlError();
1273 if (error.description().isEmpty()) {
1274 ScopedString name(scope, f->name());
1275 error.setDescription(QStringLiteral(
"Unknown exception occurred during evaluation of connected function: %1").arg(name->toQString()));
1277 if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
1278 QQmlEnginePrivate::get(qmlEngine)->warning(error);
1280 QMessageLogger(error.url().toString().toLatin1().constData(),
1281 error.line(),
nullptr).warning().noquote()
1282 << error.toString();
1289 if (connection->function.isUndefined()) {
1297 ExecutionEngine *v4 =
reinterpret_cast<ExecutionEngine*>(metaArgs[0]);
1298 if (v4 != connection->function.engine()) {
1304 ScopedValue function(scope, *
reinterpret_cast<Value*>(metaArgs[1]));
1305 ScopedValue thisObject(scope, *
reinterpret_cast<Value*>(metaArgs[2]));
1306 QObject *receiverToDisconnect =
reinterpret_cast<QObject*>(metaArgs[3]);
1307 int slotIndexToDisconnect = *
reinterpret_cast<
int*>(metaArgs[4]);
1309 if (slotIndexToDisconnect != -1) {
1311 if (connection->thisObject.isUndefined() == thisObject->isUndefined() &&
1312 (connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*connection->thisObject.valueRef(), thisObject))) {
1314 ScopedFunctionObject f(scope, connection->function.value());
1315 std::pair<QObject *,
int> connectedFunctionData = QObjectMethod::extractQtMethod(f);
1316 if (connectedFunctionData.first == receiverToDisconnect &&
1317 connectedFunctionData.second == slotIndexToDisconnect) {
1324 if (RuntimeHelpers::strictEqual(*connection->function.valueRef(), function) &&
1325 connection->thisObject.isUndefined() == thisObject->isUndefined() &&
1326 (connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*connection->thisObject.valueRef(), thisObject))) {
1367 }
else if (
argc >= 2) {
1417 "Could not find receiver of the connection, using sender as receiver. Disconnect "
1418 "explicitly (or delete the sender) to make sure the connection is removed.");
1440 THROW_GENERIC_ERROR(
"Function.prototype.disconnect: cannot disconnect from deleted QObject");
1450 }
else if (
argc >= 2) {
1482 reinterpret_cast<
void **>(&
a));
1485 reinterpret_cast<
void **>(&
a));
1493 QQueue<QObject *> queue;
1494 queue.append(parent->children());
1496 while (!queue.isEmpty()) {
1497 QObject *child = queue.dequeue();
1500 QObjectWrapper::markWrapper(child, markStack);
1501 queue.append(child->children());
1602template<
typename... Types>
1603constexpr std::size_t MaxSizeOfN = (std::max)({
sizeof(Types)...});
1605struct CallArgument {
1606 Q_DISABLE_COPY_MOVE(CallArgument);
1608 CallArgument() =
default;
1609 ~CallArgument() { cleanup(); }
1611 inline void *dataPtr();
1613 inline void initAsType(QMetaType type);
1614 inline bool fromValue(QMetaType type, ExecutionEngine *,
const Value &);
1615 inline ReturnedValue toValue(ExecutionEngine *);
1620 enum { QVariantWrappedType = -1 };
1622 inline void cleanup();
1624 template <
class T,
class M>
1625 bool fromContainerValue(
const Value &object, M CallArgument::*member);
1632 QObject *qobjectPtr;
1633 std::vector<
int> *stdVectorIntPtr;
1634 std::vector<qreal> *stdVectorRealPtr;
1635 std::vector<
bool> *stdVectorBoolPtr;
1636 std::vector<QString> *stdVectorQStringPtr;
1637 std::vector<QUrl> *stdVectorQUrlPtr;
1638#if QT_CONFIG(qml_itemmodel)
1639 std::vector<QModelIndex> *stdVectorQModelIndexPtr;
1642 char allocData[MaxSizeOfN<QVariant,
1650 qint64 q_for_alignment;
1655 QString *qstringPtr;
1656 QByteArray *qbyteArrayPtr;
1657 QVariant *qvariantPtr;
1658 QList<QObject *> *qlistPtr;
1659 QJSValue *qjsValuePtr;
1660 QJSManagedValue *qjsManagedValuePtr;
1661 QJsonArray *jsonArrayPtr;
1662 QJsonObject *jsonObjectPtr;
1663 QJsonValue *jsonValuePtr;
1666 int type = QMetaType::UnknownType;
1671 const QMetaType *argTypes, ExecutionEngine *engine, CallData *callArgs,
1676 QVarLengthArray<CallArgument, 9> args(argCount + 1);
1677 args[0].initAsType(returnType);
1678 for (
int ii = 0; ii < argCount; ++ii) {
1679 if (!args[ii + 1].fromValue(argTypes[ii], engine,
1680 callArgs->args[ii].asValue<Value>())) {
1681 qWarning() << QString::fromLatin1(
"Could not convert argument %1 from %2 to %3")
1682 .arg(ii).arg(callArgs->args[ii].asValue<Value>().toQStringNoThrow()).arg(argTypes[ii].name());
1683 const StackTrace stack = engine->stackTrace();
1684 for (
const StackFrame &frame : stack) {
1685 qWarning() <<
"\t" << frame.function + QLatin1Char(
'@') + frame.source
1687 ? (QLatin1Char(
':') + QString::number(frame.line))
1692 const bool is_signal =
1693 object.metaObject()->method(index).methodType() == QMetaMethod::Signal;
1695 qWarning() <<
"Passing incompatible arguments to signals is not supported.";
1697 return engine->throwTypeError(
1698 QLatin1String(
"Passing incompatible arguments to C++ functions from "
1699 "JavaScript is not allowed."));
1703 QVarLengthArray<
void *, 9> argData(args.size());
1704 for (
int ii = 0; ii < args.size(); ++ii)
1705 argData[ii] = args[ii].dataPtr();
1707 object.metacall(callType, index, argData.data());
1709 return args[0].toValue(engine);
1711 }
else if (returnType != QMetaType::fromType<
void>()) {
1714 arg.initAsType(returnType);
1716 void *args[] = { arg.dataPtr() };
1718 object.metacall(callType, index, args);
1720 return arg.toValue(engine);
1724 void *args[] = {
nullptr };
1725 object.metacall(callType, index, args);
1726 return Encode::undefined();
1731template<
typename Retrieve>
1733 if (conversionMetaType == QMetaType::fromType<QVariant>())
1736 const QMetaType type = retrieve();
1737 if (type == conversionMetaType)
1740 if (
const QMetaObject *conversionMetaObject = conversionMetaType.metaObject()) {
1741 if (
const QMetaObject *mo = type.metaObject(); mo && mo->inherits(conversionMetaObject))
1745 if (QMetaType::canConvert(type, conversionMetaType)) {
1746 if (conversionMetaType == QMetaType::fromType<QJSValue>()
1747 || conversionMetaType == QMetaType::fromType<
double>()
1748 || conversionMetaType == QMetaType::fromType<QString>()) {
1763
1764
1765
1766
1767
1768static int MatchScore(
const Value &actual, QMetaType conversionMetaType)
1770 const int conversionType = conversionMetaType.id();
1771 const auto convertibleScore = [&](QMetaType actualType) {
1774 if (!QMetaType::canConvert(actualType, conversionMetaType))
1779 if (conversionMetaType == QMetaType::fromType<QJSValue>())
1785 switch (conversionType) {
1786 case QMetaType::QVariant:
1787 case QMetaType::Double:
1788 case QMetaType::QString:
1798 if (actual.isNumber()) {
1799 switch (conversionType) {
1800 case QMetaType::Double:
1802 case QMetaType::Float:
1804 case QMetaType::LongLong:
1805 case QMetaType::ULongLong:
1807 case QMetaType::Long:
1808 case QMetaType::ULong:
1810 case QMetaType::Int:
1811 case QMetaType::UInt:
1813 case QMetaType::Short:
1814 case QMetaType::UShort:
1817 case QMetaType::Char:
1818 case QMetaType::UChar:
1820 case QMetaType::QJsonValue:
1823 return convertibleScore(actual.isInteger()
1824 ? QMetaType::fromType<
int>()
1825 : QMetaType::fromType<
double>());
1827 }
else if (actual.isString()) {
1828 switch (conversionType) {
1829 case QMetaType::QString:
1831 case QMetaType::QJsonValue:
1833 case QMetaType::QUrl:
1835 case QMetaType::Double:
1836 case QMetaType::Float:
1837 case QMetaType::LongLong:
1838 case QMetaType::ULongLong:
1839 case QMetaType::Int:
1840 case QMetaType::UInt:
1841 case QMetaType::Short:
1842 case QMetaType::UShort:
1843 case QMetaType::Char:
1844 case QMetaType::UChar:
1849 return convertibleScore(QMetaType::fromType<QString>());
1851 }
else if (actual.isBoolean()) {
1852 switch (conversionType) {
1853 case QMetaType::Bool:
1855 case QMetaType::QJsonValue:
1858 return convertibleScore(QMetaType::fromType<
bool>());
1860 }
else if (actual.as<DateObject>()) {
1861 switch (conversionType) {
1862 case QMetaType::QDateTime:
1864 case QMetaType::QDate:
1866 case QMetaType::QTime:
1869 return convertibleScore(QMetaType::fromType<QDateTime>());
1871 }
else if (actual.as<RegExpObject>()) {
1872 switch (conversionType) {
1873#if QT_CONFIG(regularexpression)
1874 case QMetaType::QRegularExpression:
1877 return convertibleScore(QMetaType::fromType<QRegularExpression>());
1880 return convertibleScore(QMetaType());
1883 }
else if (actual.as<ArrayBuffer>()) {
1884 switch (conversionType) {
1885 case QMetaType::QByteArray:
1888 return convertibleScore(QMetaType::fromType<QByteArray>());
1890 }
else if (actual.as<ArrayObject>()) {
1891 switch (conversionType) {
1892 case QMetaType::QJsonArray:
1894 case QMetaType::QStringList:
1895 case QMetaType::QVariantList:
1897 case QMetaType::QVector4D:
1898 case QMetaType::QMatrix4x4:
1900 case QMetaType::QVector3D:
1903 return convertibleScore(QMetaType());
1905 }
else if (actual.isNull()) {
1906 switch (conversionType) {
1907 case QMetaType::Nullptr:
1908 case QMetaType::VoidStar:
1909 case QMetaType::QObjectStar:
1910 case QMetaType::QJsonValue:
1913 if (conversionMetaType.flags().testFlag(QMetaType::IsPointer))
1916 return convertibleScore(QMetaType());
1919 }
else if (
const Object *obj = actual.as<Object>()) {
1920 if (
const VariantObject *variantObject = obj->as<VariantObject>()) {
1921 return MatchVariant(conversionMetaType, [variantObject]() {
1922 return variantObject->d()->data().metaType();
1926 if (
const QObjectWrapper *wrapper = obj->as<QObjectWrapper>()) {
1927 switch (conversionType) {
1928 case QMetaType::QObjectStar:
1931 if (conversionMetaType.flags() & QMetaType::PointerToQObject) {
1932 QObject *wrapped = wrapper->object();
1935 if (qmlobject_can_cpp_cast(wrapped, conversionMetaType.metaObject()))
1940 return convertibleScore(QMetaType::fromType<QObject *>());
1943 if (
const QQmlTypeWrapper *wrapper = obj->as<QQmlTypeWrapper>()) {
1944 const QQmlType type = wrapper->d()->type();
1945 if (type.isSingleton()) {
1946 const QMetaType metaType = type.typeId();
1947 if (metaType == conversionMetaType)
1950 if (conversionMetaType.flags() & QMetaType::PointerToQObject
1951 && metaType.flags() & QMetaType::PointerToQObject
1952 && type.metaObject()->inherits(conversionMetaType.metaObject())) {
1955 }
else if (QObject *object = wrapper->object()) {
1956 if (conversionMetaType.flags() & QMetaType::PointerToQObject
1957 && qmlobject_can_cpp_cast(object, conversionMetaType.metaObject())) {
1962 return convertibleScore(QMetaType());
1965 if (
const Sequence *sequence = obj->as<Sequence>()) {
1966 const QMetaType sequenceType = SequencePrototype::metaTypeForSequence(sequence);
1967 if (sequenceType == conversionMetaType)
1970 return convertibleScore(sequenceType);
1973 if (
const QQmlValueTypeWrapper *wrapper = obj->as<QQmlValueTypeWrapper>()) {
1974 return MatchVariant(conversionMetaType, [wrapper]() {
1975 return wrapper->d()->isVariant()
1976 ? wrapper->toVariant().metaType()
1981 if (conversionMetaType == QMetaType::fromType<QJSValue>())
1984 switch (conversionType) {
1985 case QMetaType::QJsonObject:
1986 case QMetaType::QVariantMap:
1994 return convertibleScore(QMetaType());
1999 int numDefinedArguments = callArgs->argc();
2000 while (numDefinedArguments > 0
2001 && callArgs->args[numDefinedArguments - 1].type() == StaticValue::Undefined_Type) {
2002 --numDefinedArguments;
2004 return numDefinedArguments;
2009 const QMetaObject *metaObject = object.metaObject();
2010 const int indexOfClassInfo = metaObject->indexOfClassInfo(
"QML.StrictArguments");
2011 return indexOfClassInfo != -1
2012 && metaObject->classInfo(indexOfClassInfo).value() == QByteArrayView(
"true");
2037 <<
"When matching arguments for "
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2221static bool ExactMatch(QMetaType passed, QMetaType required,
const void *data)
2223 if (required == QMetaType::fromType<QVariant>()
2224 || required == QMetaType::fromType<QJSValue>()
2225 || required == QMetaType::fromType<QJSManagedValue>()) {
2230 if (passed == QMetaType::fromType<QVariant>())
2231 passed =
static_cast<
const QVariant *>(data)->metaType();
2232 else if (passed == QMetaType::fromType<QJSPrimitiveValue>())
2233 passed =
static_cast<
const QJSPrimitiveValue *>(data)->metaType();
2236 if (passed == required)
2239 if (required == QMetaType::fromType<QJSPrimitiveValue>()) {
2240 switch (passed.id()) {
2241 case QMetaType::UnknownType:
2242 case QMetaType::Nullptr:
2243 case QMetaType::Bool:
2244 case QMetaType::Int:
2245 case QMetaType::Double:
2246 case QMetaType::QString:
2265 for (
int i = 0;
i <
argc; ++
i) {
2287void CallArgument::cleanup()
2290 case QMetaType::QString:
2291 qstringPtr->~QString();
2293 case QMetaType::QByteArray:
2294 qbyteArrayPtr->~QByteArray();
2296 case QMetaType::QVariant:
2297 case QVariantWrappedType:
2298 qvariantPtr->~QVariant();
2300 case QMetaType::QJsonArray:
2301 jsonArrayPtr->~QJsonArray();
2303 case QMetaType::QJsonObject:
2304 jsonObjectPtr->~QJsonObject();
2306 case QMetaType::QJsonValue:
2307 jsonValuePtr->~QJsonValue();
2310 if (type == qMetaTypeId<QJSValue>()) {
2311 qjsValuePtr->~QJSValue();
2315 if (type == qMetaTypeId<QJSManagedValue>()) {
2316 qjsManagedValuePtr->~QJSManagedValue();
2320 if (type == qMetaTypeId<QList<QObject *> >()) {
2321 qlistPtr->~QList<QObject *>();
2331void *CallArgument::dataPtr()
2334 case QMetaType::UnknownType:
2336 case QVariantWrappedType:
2337 return qvariantPtr->data();
2339 if (type == qMetaTypeId<std::vector<
int>>())
2340 return stdVectorIntPtr;
2341 if (type == qMetaTypeId<std::vector<qreal>>())
2342 return stdVectorRealPtr;
2343 if (type == qMetaTypeId<std::vector<
bool>>())
2344 return stdVectorBoolPtr;
2345 if (type == qMetaTypeId<std::vector<QString>>())
2346 return stdVectorQStringPtr;
2347 if (type == qMetaTypeId<std::vector<QUrl>>())
2348 return stdVectorQUrlPtr;
2349#if QT_CONFIG(qml_itemmodel)
2350 if (type == qMetaTypeId<std::vector<QModelIndex>>())
2351 return stdVectorQModelIndexPtr;
2356 return (
void *)&allocData;
2359void CallArgument::initAsType(QMetaType metaType)
2361 if (type != QMetaType::UnknownType)
2364 type = metaType.id();
2366 case QMetaType::Void:
2367 type = QMetaType::UnknownType;
2369 case QMetaType::UnknownType:
2370 case QMetaType::Int:
2371 case QMetaType::UInt:
2372 case QMetaType::Bool:
2373 case QMetaType::Double:
2374 case QMetaType::Float:
2376 case QMetaType::QObjectStar:
2377 qobjectPtr =
nullptr;
2379 case QMetaType::QString:
2380 qstringPtr =
new (&allocData) QString();
2382 case QMetaType::QVariant:
2383 qvariantPtr =
new (&allocData) QVariant();
2385 case QMetaType::QJsonArray:
2386 jsonArrayPtr =
new (&allocData) QJsonArray();
2388 case QMetaType::QJsonObject:
2389 jsonObjectPtr =
new (&allocData) QJsonObject();
2391 case QMetaType::QJsonValue:
2392 jsonValuePtr =
new (&allocData) QJsonValue();
2395 if (metaType == QMetaType::fromType<QJSValue>()) {
2396 qjsValuePtr =
new (&allocData) QJSValue();
2400 if (metaType == QMetaType::fromType<QJSManagedValue>()) {
2401 qjsManagedValuePtr =
new (&allocData) QJSManagedValue();
2405 if (metaType == QMetaType::fromType<QList<QObject *>>()) {
2406 qlistPtr =
new (&allocData) QList<QObject *>();
2410 type = QVariantWrappedType;
2411 qvariantPtr =
new (&allocData) QVariant(metaType, (
void *)
nullptr);
2417template <
class T,
class M>
2418bool CallArgument::fromContainerValue(
const Value &value, M CallArgument::*member)
2420 if (T* ptr =
static_cast<T *>(SequencePrototype::rawContainerPtr(
2421 value.as<Sequence>(), QMetaType(type)))) {
2422 (
this->*member) = ptr;
2425 (
this->*member) =
nullptr;
2429bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine,
const Value &value)
2431 if (type != QMetaType::UnknownType)
2434 type = metaType.id();
2437 case QMetaType::Int:
2438 intValue = quint32(value.toInt32());
2440 case QMetaType::UInt:
2441 intValue = quint32(value.toUInt32());
2443 case QMetaType::Bool:
2444 boolValue = value.toBoolean();
2446 case QMetaType::Double:
2447 doubleValue =
double(value.toNumber());
2449 case QMetaType::Float:
2450 floatValue =
float(value.toNumber());
2452 case QMetaType::QString:
2453 if (value.isNullOrUndefined())
2454 qstringPtr =
new (&allocData) QString();
2456 qstringPtr =
new (&allocData) QString(value.toQStringNoThrow());
2458 case QMetaType::QByteArray:
2459 qbyteArrayPtr =
new (&allocData) QByteArray();
2460 ExecutionEngine::metaTypeFromJS(value, metaType, qbyteArrayPtr);
2462 case QMetaType::QObjectStar:
2463 if (
const QObjectWrapper *qobjectWrapper = value.as<QObjectWrapper>()) {
2464 qobjectPtr = qobjectWrapper->object();
2468 if (
const QQmlTypeWrapper *qmlTypeWrapper = value.as<QQmlTypeWrapper>()) {
2469 if (qmlTypeWrapper->isSingleton()) {
2473 }
else if (QObject *obj = qmlTypeWrapper->object()) {
2481 type = QMetaType::UnknownType;
2485 qobjectPtr =
nullptr;
2486 return value.isNullOrUndefined();
2487 case QMetaType::QVariant:
2488 qvariantPtr =
new (&allocData) QVariant(ExecutionEngine::toVariant(value, QMetaType {}));
2490 case QMetaType::QJsonArray: {
2491 Scope scope(engine);
2492 ScopedObject o(scope, value);
2493 jsonArrayPtr =
new (&allocData) QJsonArray(JsonObject::toJsonArray(o));
2496 case QMetaType::QJsonObject: {
2497 Scope scope(engine);
2498 ScopedObject o(scope, value);
2499 jsonObjectPtr =
new (&allocData) QJsonObject(JsonObject::toJsonObject(o));
2502 case QMetaType::QJsonValue:
2503 jsonValuePtr =
new (&allocData) QJsonValue(JsonObject::toJsonValue(value));
2505 case QMetaType::Void:
2506 type = QMetaType::UnknownType;
2508 *qvariantPtr = QVariant();
2511 if (type == qMetaTypeId<QJSValue>()) {
2512 qjsValuePtr =
new (&allocData) QJSValue;
2513 Scope scope(engine);
2514 ScopedValue v(scope, value);
2515 QJSValuePrivate::setValue(qjsValuePtr, v);
2519 if (type == qMetaTypeId<QJSManagedValue>()) {
2520 Scope scope(engine);
2521 ScopedValue v(scope, value);
2522 qjsManagedValuePtr =
new (&allocData) QJSManagedValue;
2524 *QJSManagedValuePrivate::memberPtr(qjsManagedValuePtr) =
const_cast<Value *>(&value);
2528 if (type == qMetaTypeId<QList<QObject*> >()) {
2529 qlistPtr =
new (&allocData) QList<QObject *>();
2530 Scope scope(engine);
2531 ScopedArrayObject array(scope, value);
2533 Scoped<QObjectWrapper> qobjectWrapper(scope);
2535 uint length = array->getLength();
2536 qlistPtr->reserve(length);
2537 for (uint ii = 0; ii < length; ++ii) {
2538 QObject *o =
nullptr;
2539 qobjectWrapper = array->get(ii);
2540 if (!!qobjectWrapper)
2541 o = qobjectWrapper->object();
2542 qlistPtr->append(o);
2547 if (
const auto sequence = value.as<QV4::Sequence>()) {
2550 const qint64 length = sequence->getLength();
2552 switch (QV4::SequencePrototype::getRawContainer(
2553 sequence, qlistPtr, QMetaType::fromType<QList<QObject *>>())) {
2554 case SequencePrototype::Copied:
2555 case SequencePrototype::WasEqual:
2557 case SequencePrototype::TypeMismatch: {
2558 if (!qIsAtMostSizetypeLimit(length) || !qIsAtMostUintLimit(length))
2561 qlistPtr->reserve(length);
2562 Scoped<QObjectWrapper> qobjectWrapper(scope);
2563 for (uint ii = 0; ii < length; ++ii) {
2564 QObject *o =
nullptr;
2565 qobjectWrapper = sequence->get(ii);
2566 if (!!qobjectWrapper)
2567 o = qobjectWrapper->object();
2568 qlistPtr->append(o);
2576 if (
const QObjectWrapper *qobjectWrapper = value.as<QObjectWrapper>()) {
2577 qlistPtr->append(qobjectWrapper->object());
2581 if (
const QmlListWrapper *listWrapper = value.as<QmlListWrapper>()) {
2582 *qlistPtr = listWrapper->d()->property()->toList<QList<QObject *>>();
2586 qlistPtr->append(
nullptr);
2587 return value.isNullOrUndefined();
2590 if (metaType.flags() & (QMetaType::PointerToQObject | QMetaType::PointerToGadget)) {
2592 if (value.isNullOrUndefined()) {
2593 qvariantPtr =
new (&allocData) QVariant(metaType,
nullptr);
2599 if (type == qMetaTypeId<std::vector<
int>>()) {
2600 if (fromContainerValue<std::vector<
int>>(value, &CallArgument::stdVectorIntPtr))
2602 }
else if (type == qMetaTypeId<std::vector<qreal>>()) {
2603 if (fromContainerValue<std::vector<qreal>>(value, &CallArgument::stdVectorRealPtr))
2605 }
else if (type == qMetaTypeId<std::vector<
bool>>()) {
2606 if (fromContainerValue<std::vector<
bool>>(value, &CallArgument::stdVectorBoolPtr))
2608 }
else if (type == qMetaTypeId<std::vector<QString>>()) {
2609 if (fromContainerValue<std::vector<QString>>(value, &CallArgument::stdVectorQStringPtr))
2611 }
else if (type == qMetaTypeId<std::vector<QUrl>>()) {
2612 if (fromContainerValue<std::vector<QUrl>>(value, &CallArgument::stdVectorQUrlPtr))
2614#if QT_CONFIG(qml_itemmodel)
2615 }
else if (type == qMetaTypeId<std::vector<QModelIndex>>()) {
2616 if (fromContainerValue<std::vector<QModelIndex>>(
2617 value, &CallArgument::stdVectorQModelIndexPtr)) {
2626 qvariantPtr =
new (&allocData) QVariant(metaType);
2627 type = QVariantWrappedType;
2629 if (ExecutionEngine::metaTypeFromJS(value, metaType, qvariantPtr->data()))
2632 const QVariant v = ExecutionEngine::toVariant(value, metaType);
2633 return QMetaType::convert(v.metaType(), v.constData(), metaType, qvariantPtr->data());
2636ReturnedValue CallArgument::toValue(ExecutionEngine *engine)
2639 case QMetaType::Int:
2640 return Encode(
int(intValue));
2641 case QMetaType::UInt:
2642 return Encode((uint)intValue);
2643 case QMetaType::Bool:
2644 return Encode(boolValue);
2645 case QMetaType::Double:
2646 return Encode(doubleValue);
2647 case QMetaType::Float:
2648 return Encode(floatValue);
2649 case QMetaType::QString:
2650 return Encode(engine->newString(*qstringPtr));
2651 case QMetaType::QByteArray:
2652 return Encode(engine->newArrayBuffer(*qbyteArrayPtr));
2653 case QMetaType::QObjectStar:
2655 QQmlData::get(qobjectPtr,
true)->setImplicitDestructible();
2656 return QObjectWrapper::wrap(engine, qobjectPtr);
2657 case QMetaType::QJsonArray:
2658 return JsonObject::fromJsonArray(engine, *jsonArrayPtr);
2659 case QMetaType::QJsonObject:
2660 return JsonObject::fromJsonObject(engine, *jsonObjectPtr);
2661 case QMetaType::QJsonValue:
2662 return JsonObject::fromJsonValue(engine, *jsonValuePtr);
2663 case QMetaType::QVariant:
2664 case QVariantWrappedType: {
2665 Scope scope(engine);
2666 ScopedValue rv(scope, scope.engine->fromVariant(*qvariantPtr));
2667 Scoped<QObjectWrapper> qobjectWrapper(scope, rv);
2668 if (!!qobjectWrapper) {
2669 if (QObject *object = qobjectWrapper->object())
2670 QQmlData::get(object,
true)->setImplicitDestructible();
2672 return rv->asReturnedValue();
2678 if (type == qMetaTypeId<QJSValue>()) {
2680 QJSValuePrivate::manageStringOnV4Heap(engine, qjsValuePtr);
2681 return QJSValuePrivate::asReturnedValue(qjsValuePtr);
2684 if (type == qMetaTypeId<QJSManagedValue>())
2685 return QJSManagedValuePrivate::member(qjsManagedValuePtr)->asReturnedValue();
2687 if (type == qMetaTypeId<QList<QObject *> >()) {
2690 QList<QObject *> &list = *qlistPtr;
2691 Scope scope(engine);
2692 ScopedArrayObject array(scope, engine->newArrayObject());
2693 array->arrayReserve(list.size());
2694 ScopedValue v(scope);
2695 for (
int ii = 0; ii < list.size(); ++ii)
2696 array->arrayPut(ii, (v = QObjectWrapper::wrap(engine, list.at(ii))));
2697 array->setArrayLengthUnchecked(list.size());
2698 return array.asReturnedValue();
2701 return Encode::undefined();
2851 "%s:%d: Calling C++ methods with 'this' objects different from the one "
2852 "they were retrieved from is broken, due to historical reasons. The "
2853 "original object is used as 'this' object. You can allow the given "
2854 "'this' object to be used by setting "
2855 "'pragma NativeMethodBehavior: AcceptThisObject'",
3247 <<
QStringLiteral(
"Property '%1' of object %2 is a signal handler. You should "
3248 "not call it directly. Make it a proper function and call "
3249 "that or emit the signal.")
3281 const QObjectBiPointer key = it.key();
3282 const QObject *obj = key.isT1() ? key.asT1() : key.asT2();
3283 disconnect(obj, &QObject::destroyed,
this, &MultiplyWrappedQObjectMap::removeDestroyedObject);
3284 return QHash<QObjectBiPointer, WeakValue>::erase(it);
3289 QHash<QObjectBiPointer, WeakValue>::remove(object);
3290 QHash<QObjectBiPointer, WeakValue>::remove(
static_cast<
const QObject *>(object));
3297#include "moc_qv4qobjectwrapper_p.cpp"
QHash< QObjectBiPointer, QV4::WeakValue >::Iterator Iterator
Iterator erase(Iterator it)
static int MatchScore(const Value &actual, QMetaType conversionMetaType)
static ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index, QMetaType returnType, int argCount, const QMetaType *argTypes, ExecutionEngine *engine, CallData *callArgs, QMetaObject::Call callType=QMetaObject::InvokeMetaMethod)
static std::pair< QObject *, int > extractQtSignal(const Value &value)
static bool requiresStrictArguments(const QQmlObjectOrGadget &object)
static bool ExactMatch(QMetaType passed, QMetaType required, const void *data)
static ReturnedValue loadProperty(ExecutionEngine *v4, Heap::Object *wrapper, QObject *object, const QQmlPropertyData &property)
static void markChildQObjectsRecursively(QObject *parent, MarkStack *markStack)
int MatchVariant(QMetaType conversionMetaType, Retrieve &&retrieve)
static OptionalReturnedValue getDestroyOrToStringMethod(ExecutionEngine *v4, String *name, Heap::Object *qobj, bool *hasProperty=nullptr)
static Heap::ReferenceObject::Flags referenceFlags(ExecutionEngine *v4, const QQmlPropertyData &property)
static OptionalReturnedValue getPropertyFromImports(ExecutionEngine *v4, String *name, const QQmlRefPointer< QQmlContextData > &qmlContext, QObject *qobj, bool *hasProperty=nullptr)
static int numDefinedArguments(CallData *callArgs)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
#define PROPERTY_STORE(cpptype, value)
void init(QObject *object, int signalIndex)
void setObject(QObject *o)
PersistentValue thisObject
static void impl(int which, QSlotObjectBase *this_, QObject *receiver, void **metaArgs, bool *ret)
qsizetype maxNumArguments
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
~QObjectWrapperOwnPropertyKeyIterator() override=default