diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-09-13 14:57:47 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-09-20 08:54:42 +0200 |
commit | a2db40e6c070017960b9f815c66cab354e3466dc (patch) | |
tree | e549b977fb738cd0092d801d54025c0cff79414c /src/qml | |
parent | 85ba26c64488b76bf7fac37bc001d9762188009a (diff) |
V4: Make ExecutionEngine::toVariant() static
Wherever we need an engine in there, we also have a managed value to get
it from. This relieves us from the requirement to drag an engine around
wherever we want to call toVariant().
Change-Id: Ib95d02b5fbf5eaa494214e337c9b700e97e5e0df
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsapi/qjsmanagedvalue.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalue.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 63 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jscall_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlexpression.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertybinding_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 2 |
12 files changed, 63 insertions, 54 deletions
diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp index 8b2f367304..8d00ecb2f9 100644 --- a/src/qml/jsapi/qjsmanagedvalue.cpp +++ b/src/qml/jsapi/qjsmanagedvalue.cpp @@ -631,8 +631,8 @@ QVariant QJSManagedValue::toVariant() const return QVariant(d->doubleValue()); if (d->isString()) return QVariant(d->toQString()); - if (QV4::Managed *m = d->as<QV4::Managed>()) - return m->engine()->toVariant(*d, QMetaType{}, true); + if (d->as<QV4::Managed>()) + return QV4::ExecutionEngine::toVariant(*d, QMetaType{}, true); Q_UNREACHABLE(); return QVariant(); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 34fe760732..18ad1ebdfd 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -598,8 +598,10 @@ QVariant QJSValue::toVariant(QJSValue::ObjectConversionBehavior behavior) const if (val.isString()) return QVariant(val.toQString()); - if (QV4::Managed *m = val.as<QV4::Managed>()) - return m->engine()->toVariant(val, /*typeHint*/ QMetaType{}, behavior == RetainJSObjects); + if (val.as<QV4::Managed>()) { + return QV4::ExecutionEngine::toVariant( + val, /*typeHint*/ QMetaType{}, behavior == RetainJSObjects); + } Q_ASSERT(false); return QVariant(); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a66478d61e..43b3c6fa29 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1493,9 +1493,9 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError() // Variant conversion code typedef QSet<QV4::Heap::Object *> V4ObjectSet; -static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects); +static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects); static QObject *qtObjectFromJS(const QV4::Value &value); -static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr); +static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr); static bool convertToNativeQObject(const QV4::Value &value, QMetaType targetType, void **result); static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst); static QV4::ReturnedValue sequentialIterableToJS(QV4::ExecutionEngine *v4, const QSequentialIterable &lst); @@ -1505,10 +1505,11 @@ static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant & return v4->metaTypeToJS(value.metaType(), value.constData()); } -static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType metaType, bool createJSValueForObjects, V4ObjectSet *visitedObjects) +static QVariant toVariant( + const QV4::Value &value, QMetaType metaType, bool createJSValueForObjects, + V4ObjectSet *visitedObjects) { Q_ASSERT (!value.isEmpty()); - QV4::Scope scope(e); if (const QV4::VariantObject *v = value.as<QV4::VariantObject>()) return v->d()->data(); @@ -1522,8 +1523,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet if (metaType == QMetaType::fromType<QJSValue>()) return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(value.asReturnedValue())); - if (value.as<QV4::Object>()) { - QV4::ScopedObject object(scope, value); + if (const QV4::Object *o = value.as<QV4::Object>()) { + QV4::Scope scope(o->engine()); + QV4::ScopedObject object(scope, o); if (metaType == QMetaType::fromType<QJsonObject>() && !value.as<ArrayObject>() && !value.as<FunctionObject>()) { return QVariant::fromValue(QV4::JsonObject::toJsonObject(object)); @@ -1542,8 +1544,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet } } - if (value.as<ArrayObject>()) { - QV4::ScopedArrayObject a(scope, value); + if (const QV4::ArrayObject *o = value.as<ArrayObject>()) { + QV4::Scope scope(o->engine()); + QV4::ScopedArrayObject a(scope, o); if (metaType == QMetaType::fromType<QList<QObject *>>()) { QList<QObject *> list; uint length = a->getLength(); @@ -1590,7 +1593,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet } } - asVariant = toVariant(e, arrayValue, valueMetaType, false, visitedObjects); + asVariant = toVariant(arrayValue, valueMetaType, false, visitedObjects); if (valueMetaType == QMetaType::fromType<QVariant>()) { retnAsIterable.metaContainer().addValue(retn.data(), &asVariant); } else { @@ -1649,8 +1652,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet return d->asByteArray(); // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! - QV4::ScopedObject o(scope, value); - Q_ASSERT(o); + const QV4::Object *object = value.as<QV4::Object>(); + Q_ASSERT(object); + QV4::Scope scope(object->engine()); + QV4::ScopedObject o(scope, object); #if QT_CONFIG(regularexpression) if (QV4::RegExpObject *re = o->as<QV4::RegExpObject>()) @@ -1660,16 +1665,16 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet if (createJSValueForObjects) return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue())); - return objectToVariant(e, o, visitedObjects); + return objectToVariant(o, visitedObjects); } QVariant ExecutionEngine::toVariant(const Value &value, QMetaType typeHint, bool createJSValueForObjects) { - return ::toVariant(this, value, typeHint, createJSValueForObjects, nullptr); + return ::toVariant(value, typeHint, createJSValueForObjects, nullptr); } -static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects) +static QVariant objectToVariant(const QV4::Object *o, V4ObjectSet *visitedObjects) { Q_ASSERT(o); @@ -1689,7 +1694,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V QVariant result; if (o->as<ArrayObject>()) { - QV4::Scope scope(e); + QV4::Scope scope(o->engine()); QV4::ScopedArrayObject a(scope, o->asReturnedValue()); QV4::ScopedValue v(scope); QVariantList list; @@ -1697,7 +1702,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V int length = a->getLength(); for (int ii = 0; ii < length; ++ii) { v = a->get(ii); - list << ::toVariant(e, v, QMetaType {}, /*createJSValueForObjects*/false, visitedObjects); + list << ::toVariant(v, QMetaType {}, /*createJSValueForObjects*/false, visitedObjects); } result = list; @@ -1706,7 +1711,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V result = QVariant::fromValue(QJSValuePrivate::fromReturnedValue(f->asReturnedValue())); } else { QVariantMap map; - QV4::Scope scope(e); + QV4::Scope scope(o->engine()); QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); QV4::ScopedValue name(scope); QV4::ScopedValue val(scope); @@ -1716,7 +1721,9 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V break; QString key = name->toQStringNoThrow(); - map.insert(key, ::toVariant(e, val, /*type hint*/ QMetaType {}, /*createJSValueForObjects*/false, visitedObjects)); + map.insert(key, ::toVariant( + val, /*type hint*/ QMetaType {}, + /*createJSValueForObjects*/false, visitedObjects)); } result = map; @@ -1893,7 +1900,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) QVariantMap ExecutionEngine::variantMapFromJS(const Object *o) { - return objectToVariant(this, o).toMap(); + return objectToVariant(o).toMap(); } @@ -2452,7 +2459,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi case QMetaType::QVariantList: { const QV4::ArrayObject *a = value.as<QV4::ArrayObject>(); if (a) { - *reinterpret_cast<QVariantList *>(data) = a->engine()->toVariant( + *reinterpret_cast<QVariantList *>(data) = ExecutionEngine::toVariant( *a, /*typeHint*/QMetaType{}, /*createJSValueForObjects*/false).toList(); return true; } @@ -2467,18 +2474,20 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi break; } case QMetaType::QVariant: - if (const QV4::Managed *m = value.as<QV4::Managed>()) - *reinterpret_cast<QVariant*>(data) = m->engine()->toVariant(value, /*typeHint*/QMetaType{}, /*createJSValueForObjects*/false); - else if (value.isNull()) + if (value.as<QV4::Managed>()) { + *reinterpret_cast<QVariant*>(data) = ExecutionEngine::toVariant( + value, /*typeHint*/QMetaType{}, /*createJSValueForObjects*/false); + } else if (value.isNull()) { *reinterpret_cast<QVariant*>(data) = QVariant::fromValue(nullptr); - else if (value.isUndefined()) + } else if (value.isUndefined()) { *reinterpret_cast<QVariant*>(data) = QVariant(); - else if (value.isBoolean()) + } else if (value.isBoolean()) { *reinterpret_cast<QVariant*>(data) = QVariant(value.booleanValue()); - else if (value.isInteger()) + } else if (value.isInteger()) { *reinterpret_cast<QVariant*>(data) = QVariant(value.integerValue()); - else if (value.isDouble()) + } else if (value.isDouble()) { *reinterpret_cast<QVariant*>(data) = QVariant(value.doubleValue()); + } return true; case QMetaType::QJsonValue: *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index aa79f89231..1bca525584 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -637,10 +637,11 @@ public: QQmlError catchExceptionAsQmlError(); // variant conversions - QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects = true); + static QVariant toVariant( + const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects = true); QV4::ReturnedValue fromVariant(const QVariant &); - QVariantMap variantMapFromJS(const QV4::Object *o); + static QVariantMap variantMapFromJS(const QV4::Object *o); static bool metaTypeFromJS(const Value &value, QMetaType type, void *data); QV4::ReturnedValue metaTypeToJS(QMetaType type, const void *data); diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index 327b5bb510..cf62f2549e 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -207,7 +207,7 @@ bool convertAndCall(ExecutionEngine *engine, QObject *thisObject, // When the return type is QVariant, JS objects are to be returned as // QJSValue wrapped in QVariant. metaTypeFromJS unwraps them, unfortunately. if (resultType == QMetaType::fromType<QVariant>()) { - new (result) QVariant(scope.engine->toVariant(jsResult, QMetaType {})); + new (result) QVariant(ExecutionEngine::toVariant(jsResult, QMetaType {})); } else { resultType.construct(result); ExecutionEngine::metaTypeFromJS(jsResult, resultType, result); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index b744e45f26..54ef2c75b7 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -593,9 +593,9 @@ void QObjectWrapper::setProperty( } else { QVariant v; if (property->isQList() && propType.flags().testFlag(QMetaType::IsQmlList)) - v = scope.engine->toVariant(value, QMetaType::fromType<QList<QObject *> >()); + v = ExecutionEngine::toVariant(value, QMetaType::fromType<QList<QObject *> >()); else - v = scope.engine->toVariant(value, propType); + v = ExecutionEngine::toVariant(value, propType); QQmlRefPointer<QQmlContextData> callingQmlContext = scope.engine->callingQmlContext(); if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) { @@ -1514,7 +1514,7 @@ static int MatchScore(const Value &actual, QMetaType conversionMetaType) if (obj->as<VariantObject>()) { if (conversionType == qMetaTypeId<QVariant>()) return 0; - if (obj->engine()->toVariant(actual, QMetaType {}).metaType() == conversionMetaType) + if (ExecutionEngine::toVariant(actual, QMetaType {}).metaType() == conversionMetaType) return 0; else return 10; @@ -1537,7 +1537,7 @@ static int MatchScore(const Value &actual, QMetaType conversionMetaType) } if (obj->as<QQmlValueTypeWrapper>()) { - const QVariant v = obj->engine()->toVariant(actual, QMetaType {}); + const QVariant v = ExecutionEngine::toVariant(actual, QMetaType {}); if (v.userType() == conversionType) return 0; else if (v.canConvert(conversionMetaType)) @@ -1969,7 +1969,7 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const qobjectPtr = nullptr; return value.isNullOrUndefined(); // null and undefined are nullptr case QMetaType::QVariant: - qvariantPtr = new (&allocData) QVariant(engine->toVariant(value, QMetaType {})); + qvariantPtr = new (&allocData) QVariant(ExecutionEngine::toVariant(value, QMetaType {})); return true; case QMetaType::QJsonArray: { Scope scope(engine); @@ -2064,7 +2064,7 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const qvariantPtr = new (&allocData) QVariant(); type = QVariantWrappedType; - QVariant v = engine->toVariant(value, metaType); + QVariant v = ExecutionEngine::toVariant(value, metaType); if (v.metaType() == metaType) { *qvariantPtr = std::move(v); diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 6ed27d9d02..cb36ece6a4 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -306,7 +306,7 @@ bool Sequence::containerPutIndexed(qsizetype index, const Value &value) const qsizetype count = size(); const QMetaType valueType = valueMetaType(d()); - const QVariant element = engine()->toVariant(value, valueType, false); + const QVariant element = ExecutionEngine::toVariant(value, valueType, false); if (index < 0) return false; @@ -643,7 +643,7 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, QMetaType typeHin QV4::ScopedValue v(scope); for (quint32 i = 0; i < quint32(length); ++i) { const QMetaType valueMetaType = priv->typeId; - QVariant variant = scope.engine->toVariant(a->get(i), valueMetaType, false); + QVariant variant = ExecutionEngine::toVariant(a->get(i), valueMetaType, false); if (valueMetaType == QMetaType::fromType<QVariant>()) { meta->addValueAtEnd(result.data(), &variant); } else { diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index d009381394..9020a544ac 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -466,9 +466,6 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, const QV4::Value &result, bool isUndefined, QQmlPropertyData::WriteFlags flags) { - QQmlEngine *qmlEngine = engine(); - QV4::ExecutionEngine *v4engine = qmlEngine->handle(); - const QMetaType metaType = valueTypeData.isValid() ? valueTypeData.propType() : core.propType(); const int type = metaType.id(); @@ -480,19 +477,19 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, if (isUndefined) { } else if (core.isQList()) { if (core.propType().flags() & QMetaType::IsQmlList) - value = v4engine->toVariant(result, QMetaType::fromType<QList<QObject *> >()); + value = QV4::ExecutionEngine::toVariant(result, QMetaType::fromType<QList<QObject*>>()); else - value = v4engine->toVariant(result, core.propType()); + value = QV4::ExecutionEngine::toVariant(result, core.propType()); } else if (result.isNull() && core.isQObject()) { value = QVariant::fromValue((QObject *)nullptr); } else if (core.propType() == QMetaType::fromType<QList<QUrl>>()) { const QVariant resultVariant - = v4engine->toVariant(result, QMetaType::fromType<QList<QUrl>>()); + = QV4::ExecutionEngine::toVariant(result, QMetaType::fromType<QList<QUrl>>()); value = QVariant::fromValue(QQmlPropertyPrivate::resolveUrlsOnAssignment() ? QQmlPropertyPrivate::urlSequence(resultVariant, context()) : QQmlPropertyPrivate::urlSequence(resultVariant)); } else if (!isVarProperty && metaType != QMetaType::fromType<QJSValue>()) { - value = v4engine->toVariant(result, metaType); + value = QV4::ExecutionEngine::toVariant(result, metaType); } if (hasError()) { @@ -595,7 +592,7 @@ QVariant QQmlBinding::evaluate() ep->dereferenceScarceResources(); - return scope.engine->toVariant(result, QMetaType::fromType<QList<QObject*> >()); + return QV4::ExecutionEngine::toVariant(result, QMetaType::fromType<QList<QObject*> >()); } void QQmlBinding::expressionChanged() diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index ecece668d3..7e4483a604 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -243,7 +243,7 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined) QV4::Scope scope(engine->handle()); QV4::ScopedValue result(scope, v4value(isUndefined)); if (!hasError()) - rv = scope.engine->toVariant(result, QMetaType {}); + rv = QV4::ExecutionEngine::toVariant(result, QMetaType {}); } ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. diff --git a/src/qml/qml/qqmlpropertybinding_p.h b/src/qml/qml/qqmlpropertybinding_p.h index 9973fe42d7..50688fa245 100644 --- a/src/qml/qml/qqmlpropertybinding_p.h +++ b/src/qml/qml/qqmlpropertybinding_p.h @@ -398,7 +398,7 @@ bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) break; } - QVariant resultVariant(scope.engine->toVariant(result, metaType)); + QVariant resultVariant(QV4::ExecutionEngine::toVariant(result, metaType)); resultVariant.convert(metaType); const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr); metaType.destruct(dataPtr); diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 1ded94983e..9e08882b59 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -662,7 +662,7 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v QMetaProperty property = metaObject->property(pd.coreIndex()); Q_ASSERT(property.isValid()); - QVariant v = v4->toVariant(value, property.metaType()); + QVariant v = QV4::ExecutionEngine::toVariant(value, property.metaType()); if (property.isEnumType() && (QMetaType::Type)v.userType() == QMetaType::Double) v = v.toInt(); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 59dbfdf5f1..46e5ad96da 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1110,7 +1110,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) const const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); if (v) return v->d()->data(); - return engine->toVariant(*(md->data() + id), QMetaType {}); + return QV4::ExecutionEngine::toVariant(*(md->data() + id), QMetaType {}); } return QVariant(); } |