aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-20 01:00:04 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-20 01:00:04 +0100
commit03097d5038fe6331df97182a38fac3a9a84fe195 (patch)
tree928675991970423a6b06a8bcf5aeb79b43d2710e /src/qml/jsruntime
parentfee0fcfef08a05ed4ba9369d2352c876b514d69c (diff)
parent407e2769c7b7909fdb2979090e71fa636f109a04 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4propertykey_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp40
2 files changed, 32 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h
index cb2661f244..47867765db 100644
--- a/src/qml/jsruntime/qv4propertykey_p.h
+++ b/src/qml/jsruntime/qv4propertykey_p.h
@@ -114,7 +114,7 @@ public:
static PropertyKey fromArrayIndex(uint idx) { PropertyKey key; key.val = ArrayIndexMask | static_cast<quint64>(idx); return key; }
bool isStringOrSymbol() const { return isManaged() && val != 0; }
uint asArrayIndex() const { return (isManaged() || val == 0) ? std::numeric_limits<uint>::max() : static_cast<uint>(val & 0xffffffff); }
- uint isArrayIndex() const { return !isManaged() && val != 0; }
+ uint isArrayIndex() const { return !isManaged() && val != 0 && static_cast<uint>(val & 0xffffffff) != std::numeric_limits<uint>::max(); }
bool isValid() const { return val != 0; }
static PropertyKey fromStringOrSymbol(Heap::StringOrSymbol *b)
{ PropertyKey key; key.setM(b); return key; }
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 9344a231ff..6617dd5e89 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1144,7 +1144,7 @@ struct CallArgument {
inline void *dataPtr();
inline void initAsType(int type);
- inline void fromValue(int type, ExecutionEngine *, const QV4::Value &);
+ inline bool fromValue(int type, ExecutionEngine *, const QV4::Value &);
inline ReturnedValue toValue(ExecutionEngine *);
private:
@@ -1204,8 +1204,12 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index
// Convert all arguments.
QVarLengthArray<CallArgument, 9> args(argCount + 1);
args[0].initAsType(returnType);
- for (int ii = 0; ii < argCount; ++ii)
- args[ii + 1].fromValue(argTypes[ii], engine, callArgs->args[ii]);
+ for (int ii = 0; ii < argCount; ++ii) {
+ if (!args[ii + 1].fromValue(argTypes[ii], engine, callArgs->args[ii])) {
+ return engine->throwTypeError(QString::fromLatin1("Could not convert argument %1.")
+ .arg(ii));
+ }
+ }
QVarLengthArray<void *, 9> argData(args.count());
for (int ii = 0; ii < args.count(); ++ii)
argData[ii] = args[ii].dataPtr();
@@ -1672,7 +1676,7 @@ void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M
}
#endif
-void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
+bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
{
if (type != 0) {
cleanup();
@@ -1708,11 +1712,13 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
type = callType;
} else if (callType == QMetaType::QObjectStar) {
qobjectPtr = nullptr;
+ type = callType;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
qobjectPtr = qobjectWrapper->object();
else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QQmlTypeWrapper>())
queryEngine = qmlTypeWrapper->isSingleton();
- type = callType;
+ else if (!value.isNull() && !value.isUndefined()) // null and undefined are nullptr
+ return false;
} else if (callType == qMetaTypeId<QVariant>()) {
qvariantPtr = new (&allocData) QVariant(scope.engine->toVariant(value, -1));
type = callType;
@@ -1734,6 +1740,8 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
QObject *o = nullptr;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
o = qobjectWrapper->object();
+ else if (!value.isNull() && !value.isUndefined())
+ return false;
qlistPtr->append(o);
}
type = callType;
@@ -1782,6 +1790,15 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine);
}
#endif
+ } else if (QMetaType::typeFlags(callType)
+ & (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(callType, nullptr);
+ type = callType;
+ } else {
+ queryEngine = true;
+ }
} else {
queryEngine = true;
}
@@ -1803,15 +1820,20 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
if (!mo.isNull()) {
QObject *obj = ep->toQObject(v);
- if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo))
- obj = nullptr;
+ if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) {
+ *qvariantPtr = QVariant(callType, nullptr);
+ return false;
+ }
*qvariantPtr = QVariant(callType, &obj);
- } else {
- *qvariantPtr = QVariant(callType, (void *)nullptr);
+ return true;
}
+
+ *qvariantPtr = QVariant(callType, (void *)nullptr);
+ return false;
}
}
+ return true;
}
QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine)