aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4engine.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp29
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp23
3 files changed, 45 insertions, 11 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index bcd577c24d..bd1124beb6 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1537,6 +1537,10 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
case QMetaType::QLocale:
return QQmlLocale::wrap(this, *reinterpret_cast<const QLocale*>(ptr));
#endif
+ case QMetaType::QPixmap:
+ case QMetaType::QImage:
+ // Scarce value types
+ return QV4::Encode(newVariantObject(variant));
default:
break;
}
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 2b21591017..cb6a467c6c 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -81,19 +81,26 @@ QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl()
bool QQmlValueTypeFactoryImpl::isValueType(int idx)
{
- if (idx >= (int)QVariant::UserType) {
- return (valueType(idx) != nullptr);
- } else if (idx >= 0
- && idx != QVariant::StringList
- && idx != QMetaType::QObjectStar
- && idx != QMetaType::VoidStar
- && idx != QMetaType::Nullptr
- && idx != QMetaType::QVariant
- && idx != QMetaType::QLocale) {
+ if (idx >= QMetaType::User)
+ return valueType(idx) != nullptr;
+
+ if (idx < 0)
+ return false;
+
+ // Qt internal types
+ switch (idx) {
+ case QMetaType::QStringList:
+ case QMetaType::QObjectStar:
+ case QMetaType::VoidStar:
+ case QMetaType::Nullptr:
+ case QMetaType::QVariant:
+ case QMetaType::QLocale:
+ case QMetaType::QImage: // scarce type, keep as QVariant
+ case QMetaType::QPixmap: // scarce type, keep as QVariant
+ return false;
+ default:
return true;
}
-
- return false;
}
const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index 1ee4510e30..41fa87d848 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -33,6 +33,8 @@
#include <QJSValueIterator>
#include <private/qquickvaluetypes_p.h>
#include <private/qqmlglobal_p.h>
+#include <private/qv4engine_p.h>
+#include <private/qv4variantobject_p.h>
#include "../../shared/util.h"
#include "testtypes.h"
@@ -93,6 +95,7 @@ private slots:
void toStringConversion();
void enumerableProperties();
void enumProperties();
+ void scarceTypes();
private:
QQmlEngine engine;
@@ -1766,6 +1769,26 @@ void tst_qqmlvaluetypes::enumProperties()
QCOMPARE(enumValue.toInt(), int(g.enumProperty()));
}
+void tst_qqmlvaluetypes::scarceTypes()
+{
+ // These should not be treated as value types because we want the scarce resource
+ // mechanism to clear them when going out of scope. The scarce resource mechanism
+ // only works on QV4::VariantObject as that has an additional level of redirection.
+ QVERIFY(!QQmlValueTypeFactory::isValueType(qMetaTypeId<QImage>()));
+ QVERIFY(!QQmlValueTypeFactory::isValueType(qMetaTypeId<QPixmap>()));
+
+ QV4::ExecutionEngine engine;
+ QV4::Scope scope(&engine);
+
+ QImage img(20, 20, QImage::Format_ARGB32);
+ QV4::ScopedObject imgValue(scope, engine.fromVariant(QVariant::fromValue(img)));
+ QCOMPARE(QByteArray(imgValue->vtable()->className), QByteArray("VariantObject"));
+
+ QPixmap pixmap;
+ QV4::ScopedObject pixmapValue(scope, engine.fromVariant(QVariant::fromValue(img)));
+ QCOMPARE(QByteArray(pixmapValue->vtable()->className), QByteArray("VariantObject"));
+}
+
QTEST_MAIN(tst_qqmlvaluetypes)