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);
1226 static void impl(
int which, QSlotObjectBase *this_, QObject *receiver,
void **metaArgs,
bool *ret)
1234 if (QQmlData::wasDeleted(receiver))
1238 ExecutionEngine *v4 = This->function.engine();
1245 QQmlMetaObject::ArgTypeStorage<9> storage;
1246 QQmlMetaObject::methodParameterTypes(This->signal, &storage,
nullptr);
1248 const qsizetype argCount = std::min(storage.size(), This->maxNumArguments);
1251 ScopedFunctionObject f(scope, This->function.value());
1253 JSCallArguments jsCallData(scope, argCount);
1254 *jsCallData.thisObject = This->thisObject.isUndefined()
1255 ? v4->globalObject->asReturnedValue()
1256 : This->thisObject.value();
1257 for (qsizetype ii = 0; ii < argCount; ++ii) {
1258 QMetaType type = storage[ii];
1259 if (type == QMetaType::fromType<QVariant>()) {
1260 jsCallData.args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
1262 jsCallData.args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
1266 f->call(jsCallData);
1267 if (scope.hasException()) {
1268 QQmlError error = v4->catchExceptionAsQmlError();
1269 if (error.description().isEmpty()) {
1270 ScopedString name(scope, f->name());
1271 error.setDescription(QStringLiteral(
"Unknown exception occurred during evaluation of connected function: %1").arg(name->toQString()));
1273 if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
1274 QQmlEnginePrivate::get(qmlEngine)->warning(error);
1276 QMessageLogger(error.url().toString().toLatin1().constData(),
1277 error.line(),
nullptr).warning().noquote()
1278 << error.toString();
1285 if (connection->function.isUndefined()) {
1293 ExecutionEngine *v4 =
reinterpret_cast<ExecutionEngine*>(metaArgs[0]);
1294 if (v4 != connection->function.engine()) {
1300 ScopedValue function(scope, *
reinterpret_cast<Value*>(metaArgs[1]));
1301 ScopedValue thisObject(scope, *
reinterpret_cast<Value*>(metaArgs[2]));
1302 QObject *receiverToDisconnect =
reinterpret_cast<QObject*>(metaArgs[3]);
1303 int slotIndexToDisconnect = *
reinterpret_cast<
int*>(metaArgs[4]);
1305 if (slotIndexToDisconnect != -1) {
1307 if (connection->thisObject.isUndefined() == thisObject->isUndefined() &&
1308 (connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*connection->thisObject.valueRef(), thisObject))) {
1310 ScopedFunctionObject f(scope, connection->function.value());
1311 std::pair<QObject *,
int> connectedFunctionData = QObjectMethod::extractQtMethod(f);
1312 if (connectedFunctionData.first == receiverToDisconnect &&
1313 connectedFunctionData.second == slotIndexToDisconnect) {
1320 if (RuntimeHelpers::strictEqual(*connection->function.valueRef(), function) &&
1321 connection->thisObject.isUndefined() == thisObject->isUndefined() &&
1322 (connection->thisObject.isUndefined() || RuntimeHelpers::strictEqual(*connection->thisObject.valueRef(), thisObject))) {
1363 }
else if (
argc >= 2) {
1413 "Could not find receiver of the connection, using sender as receiver. Disconnect "
1414 "explicitly (or delete the sender) to make sure the connection is removed.");
1436 THROW_GENERIC_ERROR(
"Function.prototype.disconnect: cannot disconnect from deleted QObject");
1446 }
else if (
argc >= 2) {
1478 reinterpret_cast<
void **>(&
a));
1481 reinterpret_cast<
void **>(&
a));
1489 QQueue<QObject *> queue;
1490 queue.append(parent->children());
1492 while (!queue.isEmpty()) {
1493 QObject *child = queue.dequeue();
1496 QObjectWrapper::markWrapper(child, markStack);
1497 queue.append(child->children());
1598template<
typename... Types>
1599constexpr std::size_t MaxSizeOfN = (std::max)({
sizeof(Types)...});
1601struct CallArgument {
1602 Q_DISABLE_COPY_MOVE(CallArgument);
1604 CallArgument() =
default;
1605 ~CallArgument() { cleanup(); }
1607 inline void *dataPtr();
1609 inline void initAsType(QMetaType type);
1610 inline bool fromValue(QMetaType type, ExecutionEngine *,
const Value &);
1611 inline ReturnedValue toValue(ExecutionEngine *);
1616 enum { QVariantWrappedType = -1 };
1618 inline void cleanup();
1620 template <
class T,
class M>
1621 bool fromContainerValue(
const Value &object, M CallArgument::*member);
1628 QObject *qobjectPtr;
1629 std::vector<
int> *stdVectorIntPtr;
1630 std::vector<qreal> *stdVectorRealPtr;
1631 std::vector<
bool> *stdVectorBoolPtr;
1632 std::vector<QString> *stdVectorQStringPtr;
1633 std::vector<QUrl> *stdVectorQUrlPtr;
1634#if QT_CONFIG(qml_itemmodel)
1635 std::vector<QModelIndex> *stdVectorQModelIndexPtr;
1638 char allocData[MaxSizeOfN<QVariant,
1646 qint64 q_for_alignment;
1651 QString *qstringPtr;
1652 QByteArray *qbyteArrayPtr;
1653 QVariant *qvariantPtr;
1654 QList<QObject *> *qlistPtr;
1655 QJSValue *qjsValuePtr;
1656 QJSManagedValue *qjsManagedValuePtr;
1657 QJsonArray *jsonArrayPtr;
1658 QJsonObject *jsonObjectPtr;
1659 QJsonValue *jsonValuePtr;
1662 int type = QMetaType::UnknownType;
1667 const QMetaType *argTypes, ExecutionEngine *engine, CallData *callArgs,
1672 QVarLengthArray<CallArgument, 9> args(argCount + 1);
1673 args[0].initAsType(returnType);
1674 for (
int ii = 0; ii < argCount; ++ii) {
1675 if (!args[ii + 1].fromValue(argTypes[ii], engine,
1676 callArgs->args[ii].asValue<Value>())) {
1677 qWarning() << QString::fromLatin1(
"Could not convert argument %1 from %2 to %3")
1678 .arg(ii).arg(callArgs->args[ii].asValue<Value>().toQStringNoThrow()).arg(argTypes[ii].name());
1679 const StackTrace stack = engine->stackTrace();
1680 for (
const StackFrame &frame : stack) {
1681 qWarning() <<
"\t" << frame.function + QLatin1Char(
'@') + frame.source
1683 ? (QLatin1Char(
':') + QString::number(frame.line))
1688 const bool is_signal =
1689 object.metaObject()->method(index).methodType() == QMetaMethod::Signal;
1691 qWarning() <<
"Passing incompatible arguments to signals is not supported.";
1693 return engine->throwTypeError(
1694 QLatin1String(
"Passing incompatible arguments to C++ functions from "
1695 "JavaScript is not allowed."));
1699 QVarLengthArray<
void *, 9> argData(args.size());
1700 for (
int ii = 0; ii < args.size(); ++ii)
1701 argData[ii] = args[ii].dataPtr();
1703 object.metacall(callType, index, argData.data());
1705 return args[0].toValue(engine);
1707 }
else if (returnType != QMetaType::fromType<
void>()) {
1710 arg.initAsType(returnType);
1712 void *args[] = { arg.dataPtr() };
1714 object.metacall(callType, index, args);
1716 return arg.toValue(engine);
1720 void *args[] = {
nullptr };
1721 object.metacall(callType, index, args);
1722 return Encode::undefined();
1727template<
typename Retrieve>
1729 if (conversionMetaType == QMetaType::fromType<QVariant>())
1732 const QMetaType type = retrieve();
1733 if (type == conversionMetaType)
1736 if (
const QMetaObject *conversionMetaObject = conversionMetaType.metaObject()) {
1737 if (
const QMetaObject *mo = type.metaObject(); mo && mo->inherits(conversionMetaObject))
1741 if (QMetaType::canConvert(type, conversionMetaType)) {
1742 if (conversionMetaType == QMetaType::fromType<QJSValue>()
1743 || conversionMetaType == QMetaType::fromType<
double>()
1744 || conversionMetaType == QMetaType::fromType<QString>()) {
1759
1760
1761
1762
1763
1764static int MatchScore(
const Value &actual, QMetaType conversionMetaType)
1766 const int conversionType = conversionMetaType.id();
1767 const auto convertibleScore = [&](QMetaType actualType) {
1770 if (!QMetaType::canConvert(actualType, conversionMetaType))
1775 if (conversionMetaType == QMetaType::fromType<QJSValue>())
1781 switch (conversionType) {
1782 case QMetaType::QVariant:
1783 case QMetaType::Double:
1784 case QMetaType::QString:
1794 if (actual.isNumber()) {
1795 switch (conversionType) {
1796 case QMetaType::Double:
1798 case QMetaType::Float:
1800 case QMetaType::LongLong:
1801 case QMetaType::ULongLong:
1803 case QMetaType::Long:
1804 case QMetaType::ULong:
1806 case QMetaType::Int:
1807 case QMetaType::UInt:
1809 case QMetaType::Short:
1810 case QMetaType::UShort:
1813 case QMetaType::Char:
1814 case QMetaType::UChar:
1816 case QMetaType::QJsonValue:
1819 return convertibleScore(actual.isInteger()
1820 ? QMetaType::fromType<
int>()
1821 : QMetaType::fromType<
double>());
1823 }
else if (actual.isString()) {
1824 switch (conversionType) {
1825 case QMetaType::QString:
1827 case QMetaType::QJsonValue:
1829 case QMetaType::QUrl:
1831 case QMetaType::Double:
1832 case QMetaType::Float:
1833 case QMetaType::LongLong:
1834 case QMetaType::ULongLong:
1835 case QMetaType::Int:
1836 case QMetaType::UInt:
1837 case QMetaType::Short:
1838 case QMetaType::UShort:
1839 case QMetaType::Char:
1840 case QMetaType::UChar:
1845 return convertibleScore(QMetaType::fromType<QString>());
1847 }
else if (actual.isBoolean()) {
1848 switch (conversionType) {
1849 case QMetaType::Bool:
1851 case QMetaType::QJsonValue:
1854 return convertibleScore(QMetaType::fromType<
bool>());
1856 }
else if (actual.as<DateObject>()) {
1857 switch (conversionType) {
1858 case QMetaType::QDateTime:
1860 case QMetaType::QDate:
1862 case QMetaType::QTime:
1865 return convertibleScore(QMetaType::fromType<QDateTime>());
1867 }
else if (actual.as<RegExpObject>()) {
1868 switch (conversionType) {
1869#if QT_CONFIG(regularexpression)
1870 case QMetaType::QRegularExpression:
1873 return convertibleScore(QMetaType::fromType<QRegularExpression>());
1876 return convertibleScore(QMetaType());
1879 }
else if (actual.as<ArrayBuffer>()) {
1880 switch (conversionType) {
1881 case QMetaType::QByteArray:
1884 return convertibleScore(QMetaType::fromType<QByteArray>());
1886 }
else if (actual.as<ArrayObject>()) {
1887 switch (conversionType) {
1888 case QMetaType::QJsonArray:
1890 case QMetaType::QStringList:
1891 case QMetaType::QVariantList:
1893 case QMetaType::QVector4D:
1894 case QMetaType::QMatrix4x4:
1896 case QMetaType::QVector3D:
1899 return convertibleScore(QMetaType());
1901 }
else if (actual.isNull()) {
1902 switch (conversionType) {
1903 case QMetaType::Nullptr:
1904 case QMetaType::VoidStar:
1905 case QMetaType::QObjectStar:
1906 case QMetaType::QJsonValue:
1909 if (conversionMetaType.flags().testFlag(QMetaType::IsPointer))
1912 return convertibleScore(QMetaType());
1915 }
else if (
const Object *obj = actual.as<Object>()) {
1916 if (
const VariantObject *variantObject = obj->as<VariantObject>()) {
1917 return MatchVariant(conversionMetaType, [variantObject]() {
1918 return variantObject->d()->data().metaType();
1922 if (
const QObjectWrapper *wrapper = obj->as<QObjectWrapper>()) {
1923 switch (conversionType) {
1924 case QMetaType::QObjectStar:
1927 if (conversionMetaType.flags() & QMetaType::PointerToQObject) {
1928 QObject *wrapped = wrapper->object();
1931 if (qmlobject_can_cpp_cast(wrapped, conversionMetaType.metaObject()))
1936 return convertibleScore(QMetaType::fromType<QObject *>());
1939 if (
const QQmlTypeWrapper *wrapper = obj->as<QQmlTypeWrapper>()) {
1940 const QQmlType type = wrapper->d()->type();
1941 if (type.isSingleton()) {
1942 const QMetaType metaType = type.typeId();
1943 if (metaType == conversionMetaType)
1946 if (conversionMetaType.flags() & QMetaType::PointerToQObject
1947 && metaType.flags() & QMetaType::PointerToQObject
1948 && type.metaObject()->inherits(conversionMetaType.metaObject())) {
1951 }
else if (QObject *object = wrapper->object()) {
1952 if (conversionMetaType.flags() & QMetaType::PointerToQObject
1953 && qmlobject_can_cpp_cast(object, conversionMetaType.metaObject())) {
1958 return convertibleScore(QMetaType());
1961 if (
const Sequence *sequence = obj->as<Sequence>()) {
1962 const QMetaType sequenceType = SequencePrototype::metaTypeForSequence(sequence);
1963 if (sequenceType == conversionMetaType)
1966 return convertibleScore(sequenceType);
1969 if (
const QQmlValueTypeWrapper *wrapper = obj->as<QQmlValueTypeWrapper>()) {
1970 return MatchVariant(conversionMetaType, [wrapper]() {
1971 return wrapper->d()->isVariant()
1972 ? wrapper->toVariant().metaType()
1977 if (conversionMetaType == QMetaType::fromType<QJSValue>())
1980 switch (conversionType) {
1981 case QMetaType::QJsonObject:
1982 case QMetaType::QVariantMap:
1990 return convertibleScore(QMetaType());
1995 int numDefinedArguments = callArgs->argc();
1996 while (numDefinedArguments > 0
1997 && callArgs->args[numDefinedArguments - 1].type() == StaticValue::Undefined_Type) {
1998 --numDefinedArguments;
2000 return numDefinedArguments;
2005 const QMetaObject *metaObject = object.metaObject();
2006 const int indexOfClassInfo = metaObject->indexOfClassInfo(
"QML.StrictArguments");
2007 return indexOfClassInfo != -1
2008 && metaObject->classInfo(indexOfClassInfo).value() == QByteArrayView(
"true");
2033 <<
"When matching arguments for "
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2217static bool ExactMatch(QMetaType passed, QMetaType required,
const void *data)
2219 if (required == QMetaType::fromType<QVariant>()
2220 || required == QMetaType::fromType<QJSValue>()
2221 || required == QMetaType::fromType<QJSManagedValue>()) {
2226 if (passed == QMetaType::fromType<QVariant>())
2227 passed =
static_cast<
const QVariant *>(data)->metaType();
2228 else if (passed == QMetaType::fromType<QJSPrimitiveValue>())
2229 passed =
static_cast<
const QJSPrimitiveValue *>(data)->metaType();
2232 if (passed == required)
2235 if (required == QMetaType::fromType<QJSPrimitiveValue>()) {
2236 switch (passed.id()) {
2237 case QMetaType::UnknownType:
2238 case QMetaType::Nullptr:
2239 case QMetaType::Bool:
2240 case QMetaType::Int:
2241 case QMetaType::Double:
2242 case QMetaType::QString:
2261 for (
int i = 0;
i <
argc; ++
i) {
2283void CallArgument::cleanup()
2286 case QMetaType::QString:
2287 qstringPtr->~QString();
2289 case QMetaType::QByteArray:
2290 qbyteArrayPtr->~QByteArray();
2292 case QMetaType::QVariant:
2293 case QVariantWrappedType:
2294 qvariantPtr->~QVariant();
2296 case QMetaType::QJsonArray:
2297 jsonArrayPtr->~QJsonArray();
2299 case QMetaType::QJsonObject:
2300 jsonObjectPtr->~QJsonObject();
2302 case QMetaType::QJsonValue:
2303 jsonValuePtr->~QJsonValue();
2306 if (type == qMetaTypeId<QJSValue>()) {
2307 qjsValuePtr->~QJSValue();
2311 if (type == qMetaTypeId<QJSManagedValue>()) {
2312 qjsManagedValuePtr->~QJSManagedValue();
2316 if (type == qMetaTypeId<QList<QObject *> >()) {
2317 qlistPtr->~QList<QObject *>();
2327void *CallArgument::dataPtr()
2330 case QMetaType::UnknownType:
2332 case QVariantWrappedType:
2333 return qvariantPtr->data();
2335 if (type == qMetaTypeId<std::vector<
int>>())
2336 return stdVectorIntPtr;
2337 if (type == qMetaTypeId<std::vector<qreal>>())
2338 return stdVectorRealPtr;
2339 if (type == qMetaTypeId<std::vector<
bool>>())
2340 return stdVectorBoolPtr;
2341 if (type == qMetaTypeId<std::vector<QString>>())
2342 return stdVectorQStringPtr;
2343 if (type == qMetaTypeId<std::vector<QUrl>>())
2344 return stdVectorQUrlPtr;
2345#if QT_CONFIG(qml_itemmodel)
2346 if (type == qMetaTypeId<std::vector<QModelIndex>>())
2347 return stdVectorQModelIndexPtr;
2352 return (
void *)&allocData;
2355void CallArgument::initAsType(QMetaType metaType)
2357 if (type != QMetaType::UnknownType)
2360 type = metaType.id();
2362 case QMetaType::Void:
2363 type = QMetaType::UnknownType;
2365 case QMetaType::UnknownType:
2366 case QMetaType::Int:
2367 case QMetaType::UInt:
2368 case QMetaType::Bool:
2369 case QMetaType::Double:
2370 case QMetaType::Float:
2372 case QMetaType::QObjectStar:
2373 qobjectPtr =
nullptr;
2375 case QMetaType::QString:
2376 qstringPtr =
new (&allocData) QString();
2378 case QMetaType::QVariant:
2379 qvariantPtr =
new (&allocData) QVariant();
2381 case QMetaType::QJsonArray:
2382 jsonArrayPtr =
new (&allocData) QJsonArray();
2384 case QMetaType::QJsonObject:
2385 jsonObjectPtr =
new (&allocData) QJsonObject();
2387 case QMetaType::QJsonValue:
2388 jsonValuePtr =
new (&allocData) QJsonValue();
2391 if (metaType == QMetaType::fromType<QJSValue>()) {
2392 qjsValuePtr =
new (&allocData) QJSValue();
2396 if (metaType == QMetaType::fromType<QJSManagedValue>()) {
2397 qjsManagedValuePtr =
new (&allocData) QJSManagedValue();
2401 if (metaType == QMetaType::fromType<QList<QObject *>>()) {
2402 qlistPtr =
new (&allocData) QList<QObject *>();
2406 type = QVariantWrappedType;
2407 qvariantPtr =
new (&allocData) QVariant(metaType, (
void *)
nullptr);
2413template <
class T,
class M>
2414bool CallArgument::fromContainerValue(
const Value &value, M CallArgument::*member)
2416 if (T* ptr =
static_cast<T *>(SequencePrototype::rawContainerPtr(
2417 value.as<Sequence>(), QMetaType(type)))) {
2418 (
this->*member) = ptr;
2421 (
this->*member) =
nullptr;
2425bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine,
const Value &value)
2427 if (type != QMetaType::UnknownType)
2430 type = metaType.id();
2433 case QMetaType::Int:
2434 intValue = quint32(value.toInt32());
2436 case QMetaType::UInt:
2437 intValue = quint32(value.toUInt32());
2439 case QMetaType::Bool:
2440 boolValue = value.toBoolean();
2442 case QMetaType::Double:
2443 doubleValue =
double(value.toNumber());
2445 case QMetaType::Float:
2446 floatValue =
float(value.toNumber());
2448 case QMetaType::QString:
2449 if (value.isNullOrUndefined())
2450 qstringPtr =
new (&allocData) QString();
2452 qstringPtr =
new (&allocData) QString(value.toQStringNoThrow());
2454 case QMetaType::QByteArray:
2455 qbyteArrayPtr =
new (&allocData) QByteArray();
2456 ExecutionEngine::metaTypeFromJS(value, metaType, qbyteArrayPtr);
2458 case QMetaType::QObjectStar:
2459 if (
const QObjectWrapper *qobjectWrapper = value.as<QObjectWrapper>()) {
2460 qobjectPtr = qobjectWrapper->object();
2464 if (
const QQmlTypeWrapper *qmlTypeWrapper = value.as<QQmlTypeWrapper>()) {
2465 if (qmlTypeWrapper->isSingleton()) {
2469 }
else if (QObject *obj = qmlTypeWrapper->object()) {
2477 type = QMetaType::UnknownType;
2481 qobjectPtr =
nullptr;
2482 return value.isNullOrUndefined();
2483 case QMetaType::QVariant:
2484 qvariantPtr =
new (&allocData) QVariant(ExecutionEngine::toVariant(value, QMetaType {}));
2486 case QMetaType::QJsonArray: {
2487 Scope scope(engine);
2488 ScopedObject o(scope, value);
2489 jsonArrayPtr =
new (&allocData) QJsonArray(JsonObject::toJsonArray(o));
2492 case QMetaType::QJsonObject: {
2493 Scope scope(engine);
2494 ScopedObject o(scope, value);
2495 jsonObjectPtr =
new (&allocData) QJsonObject(JsonObject::toJsonObject(o));
2498 case QMetaType::QJsonValue:
2499 jsonValuePtr =
new (&allocData) QJsonValue(JsonObject::toJsonValue(value));
2501 case QMetaType::Void:
2502 type = QMetaType::UnknownType;
2504 *qvariantPtr = QVariant();
2507 if (type == qMetaTypeId<QJSValue>()) {
2508 qjsValuePtr =
new (&allocData) QJSValue;
2509 Scope scope(engine);
2510 ScopedValue v(scope, value);
2511 QJSValuePrivate::setValue(qjsValuePtr, v);
2515 if (type == qMetaTypeId<QJSManagedValue>()) {
2516 Scope scope(engine);
2517 ScopedValue v(scope, value);
2518 qjsManagedValuePtr =
new (&allocData) QJSManagedValue;
2520 *QJSManagedValuePrivate::memberPtr(qjsManagedValuePtr) =
const_cast<Value *>(&value);
2524 if (type == qMetaTypeId<QList<QObject*> >()) {
2525 qlistPtr =
new (&allocData) QList<QObject *>();
2526 Scope scope(engine);
2527 ScopedArrayObject array(scope, value);
2529 Scoped<QObjectWrapper> qobjectWrapper(scope);
2531 uint length = array->getLength();
2532 qlistPtr->reserve(length);
2533 for (uint ii = 0; ii < length; ++ii) {
2534 QObject *o =
nullptr;
2535 qobjectWrapper = array->get(ii);
2536 if (!!qobjectWrapper)
2537 o = qobjectWrapper->object();
2538 qlistPtr->append(o);
2543 if (
const auto sequence = value.as<QV4::Sequence>()) {
2546 const qint64 length = sequence->getLength();
2548 switch (QV4::SequencePrototype::getRawContainer(
2549 sequence, qlistPtr, QMetaType::fromType<QList<QObject *>>())) {
2550 case SequencePrototype::Copied:
2551 case SequencePrototype::WasEqual:
2553 case SequencePrototype::TypeMismatch: {
2554 if (!qIsAtMostSizetypeLimit(length) || !qIsAtMostUintLimit(length))
2557 qlistPtr->reserve(length);
2558 Scoped<QObjectWrapper> qobjectWrapper(scope);
2559 for (uint ii = 0; ii < length; ++ii) {
2560 QObject *o =
nullptr;
2561 qobjectWrapper = sequence->get(ii);
2562 if (!!qobjectWrapper)
2563 o = qobjectWrapper->object();
2564 qlistPtr->append(o);
2572 if (
const QObjectWrapper *qobjectWrapper = value.as<QObjectWrapper>()) {
2573 qlistPtr->append(qobjectWrapper->object());
2577 if (
const QmlListWrapper *listWrapper = value.as<QmlListWrapper>()) {
2578 *qlistPtr = listWrapper->d()->property()->toList<QList<QObject *>>();
2582 qlistPtr->append(
nullptr);
2583 return value.isNullOrUndefined();
2586 if (metaType.flags() & (QMetaType::PointerToQObject | QMetaType::PointerToGadget)) {
2588 if (value.isNullOrUndefined()) {
2589 qvariantPtr =
new (&allocData) QVariant(metaType,
nullptr);
2595 if (type == qMetaTypeId<std::vector<
int>>()) {
2596 if (fromContainerValue<std::vector<
int>>(value, &CallArgument::stdVectorIntPtr))
2598 }
else if (type == qMetaTypeId<std::vector<qreal>>()) {
2599 if (fromContainerValue<std::vector<qreal>>(value, &CallArgument::stdVectorRealPtr))
2601 }
else if (type == qMetaTypeId<std::vector<
bool>>()) {
2602 if (fromContainerValue<std::vector<
bool>>(value, &CallArgument::stdVectorBoolPtr))
2604 }
else if (type == qMetaTypeId<std::vector<QString>>()) {
2605 if (fromContainerValue<std::vector<QString>>(value, &CallArgument::stdVectorQStringPtr))
2607 }
else if (type == qMetaTypeId<std::vector<QUrl>>()) {
2608 if (fromContainerValue<std::vector<QUrl>>(value, &CallArgument::stdVectorQUrlPtr))
2610#if QT_CONFIG(qml_itemmodel)
2611 }
else if (type == qMetaTypeId<std::vector<QModelIndex>>()) {
2612 if (fromContainerValue<std::vector<QModelIndex>>(
2613 value, &CallArgument::stdVectorQModelIndexPtr)) {
2622 qvariantPtr =
new (&allocData) QVariant(metaType);
2623 type = QVariantWrappedType;
2625 if (ExecutionEngine::metaTypeFromJS(value, metaType, qvariantPtr->data()))
2628 const QVariant v = ExecutionEngine::toVariant(value, metaType);
2629 return QMetaType::convert(v.metaType(), v.constData(), metaType, qvariantPtr->data());
2632ReturnedValue CallArgument::toValue(ExecutionEngine *engine)
2635 case QMetaType::Int:
2636 return Encode(
int(intValue));
2637 case QMetaType::UInt:
2638 return Encode((uint)intValue);
2639 case QMetaType::Bool:
2640 return Encode(boolValue);
2641 case QMetaType::Double:
2642 return Encode(doubleValue);
2643 case QMetaType::Float:
2644 return Encode(floatValue);
2645 case QMetaType::QString:
2646 return Encode(engine->newString(*qstringPtr));
2647 case QMetaType::QByteArray:
2648 return Encode(engine->newArrayBuffer(*qbyteArrayPtr));
2649 case QMetaType::QObjectStar:
2651 QQmlData::get(qobjectPtr,
true)->setImplicitDestructible();
2652 return QObjectWrapper::wrap(engine, qobjectPtr);
2653 case QMetaType::QJsonArray:
2654 return JsonObject::fromJsonArray(engine, *jsonArrayPtr);
2655 case QMetaType::QJsonObject:
2656 return JsonObject::fromJsonObject(engine, *jsonObjectPtr);
2657 case QMetaType::QJsonValue:
2658 return JsonObject::fromJsonValue(engine, *jsonValuePtr);
2659 case QMetaType::QVariant:
2660 case QVariantWrappedType: {
2661 Scope scope(engine);
2662 ScopedValue rv(scope, scope.engine->fromVariant(*qvariantPtr));
2663 Scoped<QObjectWrapper> qobjectWrapper(scope, rv);
2664 if (!!qobjectWrapper) {
2665 if (QObject *object = qobjectWrapper->object())
2666 QQmlData::get(object,
true)->setImplicitDestructible();
2668 return rv->asReturnedValue();
2674 if (type == qMetaTypeId<QJSValue>()) {
2676 QJSValuePrivate::manageStringOnV4Heap(engine, qjsValuePtr);
2677 return QJSValuePrivate::asReturnedValue(qjsValuePtr);
2680 if (type == qMetaTypeId<QJSManagedValue>())
2681 return QJSManagedValuePrivate::member(qjsManagedValuePtr)->asReturnedValue();
2683 if (type == qMetaTypeId<QList<QObject *> >()) {
2686 QList<QObject *> &list = *qlistPtr;
2687 Scope scope(engine);
2688 ScopedArrayObject array(scope, engine->newArrayObject());
2689 array->arrayReserve(list.size());
2690 ScopedValue v(scope);
2691 for (
int ii = 0; ii < list.size(); ++ii)
2692 array->arrayPut(ii, (v = QObjectWrapper::wrap(engine, list.at(ii))));
2693 array->setArrayLengthUnchecked(list.size());
2694 return array.asReturnedValue();
2697 return Encode::undefined();
2847 "%s:%d: Calling C++ methods with 'this' objects different from the one "
2848 "they were retrieved from is broken, due to historical reasons. The "
2849 "original object is used as 'this' object. You can allow the given "
2850 "'this' object to be used by setting "
2851 "'pragma NativeMethodBehavior: AcceptThisObject'",
3243 <<
QStringLiteral(
"Property '%1' of object %2 is a signal handler. You should "
3244 "not call it directly. Make it a proper function and call "
3245 "that or emit the signal.")
3277 const QObjectBiPointer key = it.key();
3278 const QObject *obj = key.isT1() ? key.asT1() : key.asT2();
3279 disconnect(obj, &QObject::destroyed,
this, &MultiplyWrappedQObjectMap::removeDestroyedObject);
3280 return QHash<QObjectBiPointer, WeakValue>::erase(it);
3285 QHash<QObjectBiPointer, WeakValue>::remove(object);
3286 QHash<QObjectBiPointer, WeakValue>::remove(
static_cast<
const QObject *>(object));
3293#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