aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4engine.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-07-26 14:12:26 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-07-27 14:42:00 +0200
commitafe96c4d633146df477012975824b8ab65034239 (patch)
tree3ffc0c716de580236b173d93079ca27f5e308064 /src/qml/jsruntime/qv4engine.cpp
parent3d74e9120583ff911fba97b21b008cf29fcbe3f7 (diff)
QML: Do convert objects with prototypes to QVariantMap
While we shouldn't convert to QVariantMap if only QVariant is requested, we should convert if QVariantMap is explicitly requested. QVariant can hold QJSValue which is a better fit for objects with properties. QVariantMap cannot hold QJSValue. A best effort conversion is still better than an empty map. Amends commit 47678c682f168eb6d5020383ea75fe1700e8c4f6. Pick-to: 6.6 6.5 Fixes: QTBUG-115523 Change-Id: Iaa96809ee411dc0db95311c641c4e3f1f51a6026 Reviewed-by: Amanda Hamblin-Trué <amanda.hamblin-true@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index f73d881885..087dce5295 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1688,6 +1688,26 @@ QVariant ExecutionEngine::toVariant(
return ::toVariant(value, typeHint, createJSValueForObjectsAndSymbols, nullptr);
}
+static QVariantMap objectToVariantMap(const QV4::Object *o, V4ObjectSet *visitedObjects)
+{
+ QVariantMap map;
+ QV4::Scope scope(o->engine());
+ QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
+ QV4::ScopedValue name(scope);
+ QV4::ScopedValue val(scope);
+ while (1) {
+ name = it.nextPropertyNameAsString(val);
+ if (name->isNull())
+ break;
+
+ QString key = name->toQStringNoThrow();
+ map.insert(key, ::toVariant(
+ val, /*type hint*/ QMetaType {},
+ /*createJSValueForObjectsAndSymbols*/false, visitedObjects));
+ }
+ return map;
+}
+
static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects)
{
Q_ASSERT(o);
@@ -1722,23 +1742,7 @@ static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObject
result = list;
} else if (o->getPrototypeOf() == o->engine()->objectPrototype()->d()) {
- QVariantMap map;
- QV4::Scope scope(o->engine());
- QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
- QV4::ScopedValue name(scope);
- QV4::ScopedValue val(scope);
- while (1) {
- name = it.nextPropertyNameAsString(val);
- if (name->isNull())
- break;
-
- QString key = name->toQStringNoThrow();
- map.insert(key, ::toVariant(
- val, /*type hint*/ QMetaType {},
- /*createJSValueForObjectsAndSymbols*/false, visitedObjects));
- }
-
- result = map;
+ result = objectToVariantMap(o, visitedObjects);
} else {
// If it's not a plain object, we can only save it as QJSValue.
result = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue()));
@@ -1961,7 +1965,10 @@ ReturnedValue ExecutionEngine::fromVariant(
QVariantMap ExecutionEngine::variantMapFromJS(const Object *o)
{
- return objectToVariant(o).toMap();
+ Q_ASSERT(o);
+ V4ObjectSet visitedObjects;
+ visitedObjects.insert(o->d());
+ return objectToVariantMap(o, &visitedObjects);
}
// Converts a QVariantMap to JS.