diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsapi/qjsengine_p.h | 27 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 31 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlcontext.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmllist.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 39 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 15 |
14 files changed, 68 insertions, 89 deletions
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index acb36f4902..c38b4ea3bb 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -83,35 +83,8 @@ public: void uiLanguageChanged() { Q_Q(QJSEngine); if (q) q->uiLanguageChanged(); } Q_OBJECT_BINDABLE_PROPERTY(QJSEnginePrivate, QString, uiLanguage, &QJSEnginePrivate::uiLanguageChanged); - - // These methods may be called from the QML loader thread - inline QQmlRefPointer<QQmlPropertyCache> cache(QObject *obj, QTypeRevision version = QTypeRevision()); }; -/*! -Returns a QQmlPropertyCache for \a obj if one is available. - -If \a obj is null, being deleted or contains a dynamic meta object 0 -is returned. - -The returned cache is not referenced, so if it is to be stored, call addref(). - -XXX thread There is a potential future race condition in this and all the cache() -functions. As the QQmlPropertyCache is returned unreferenced, when called -from the loader thread, it is possible that the cache will have been dereferenced -and deleted before the loader thread has a chance to use or reference it. This -can't currently happen as the cache holds a reference to the -QQmlPropertyCache until the QQmlEngine is destroyed. -*/ -QQmlRefPointer<QQmlPropertyCache> QJSEnginePrivate::cache(QObject *obj, QTypeRevision version) -{ - if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) - return QQmlRefPointer<QQmlPropertyCache>(); - - const QMetaObject *mo = obj->metaObject(); - return QQmlMetaType::propertyCache(mo, version); -} - QT_END_NAMESPACE #endif // QJSENGINE_P_H diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 07f6b15f5c..a597aa881f 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -234,15 +234,14 @@ void QObjectWrapper::initializeBindings(ExecutionEngine *engine) } QQmlPropertyData *QObjectWrapper::findProperty( - ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext, String *name, + const QQmlRefPointer<QQmlContextData> &qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const { - QObject *o = d()->object(); - return findProperty(engine, o, qmlContext, name, revisionMode, local); + return findProperty(d()->object(), qmlContext, name, revisionMode, local); } QQmlPropertyData *QObjectWrapper::findProperty( - ExecutionEngine *engine, QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext, + QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) { Q_UNUSED(revisionMode); @@ -252,7 +251,7 @@ QQmlPropertyData *QObjectWrapper::findProperty( if (ddata && ddata->propertyCache) result = ddata->propertyCache->property(name, o, qmlContext); else - result = QQmlPropertyCache::property(engine->jsEngine(), o, name, qmlContext, local); + result = QQmlPropertyCache::property(o, name, qmlContext, local); return result; } @@ -357,7 +356,7 @@ ReturnedValue QObjectWrapper::getQmlProperty( return *methodValue; QQmlPropertyData local; - QQmlPropertyData *result = findProperty(v4, qmlContext, name, revisionMode, &local); + QQmlPropertyData *result = findProperty(qmlContext, name, revisionMode, &local); if (!result) { // Check for attached properties @@ -400,7 +399,7 @@ ReturnedValue QObjectWrapper::getQmlProperty( QQmlData *ddata = QQmlData::get(object, false); QQmlPropertyData local; - QQmlPropertyData *result = findProperty(engine, object, qmlContext, name, revisionMode, &local); + QQmlPropertyData *result = findProperty(object, qmlContext, name, revisionMode, &local); if (result) { if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) { @@ -455,7 +454,7 @@ bool QObjectWrapper::setQmlProperty( return false; QQmlPropertyData local; - QQmlPropertyData *result = QQmlPropertyCache::property(engine->jsEngine(), object, name, qmlContext, &local); + QQmlPropertyData *result = QQmlPropertyCache::property(object, name, qmlContext, &local); if (!result) return false; @@ -757,13 +756,11 @@ bool QObjectWrapper::virtualIsEqualTo(Managed *a, Managed *b) ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object) { - if (QJSEngine *jsEngine = engine->jsEngine()) { - if (QQmlRefPointer<QQmlPropertyCache> cache = QQmlData::ensurePropertyCache(jsEngine, object)) { - ReturnedValue result = QV4::Encode::null(); - void *args[] = { &result, &engine }; - if (cache->callJSFactoryMethod(object, args)) - return result; - } + if (QQmlRefPointer<QQmlPropertyCache> cache = QQmlData::ensurePropertyCache(object)) { + ReturnedValue result = QV4::Encode::null(); + void *args[] = { &result, &engine }; + if (cache->callJSFactoryMethod(object, args)) + return result; } return (engine->memoryManager->allocate<QV4::QObjectWrapper>(object))->asReturnedValue(); } @@ -827,7 +824,7 @@ PropertyAttributes QObjectWrapper::virtualGetOwnProperty(const Managed *m, Prope ScopedString n(scope, id.asStringOrSymbol()); QQmlRefPointer<QQmlContextData> qmlContext = scope.engine->callingQmlContext(); QQmlPropertyData local; - if (that->findProperty(scope.engine, qmlContext, n, IgnoreRevision, &local) + if (that->findProperty(qmlContext, n, IgnoreRevision, &local) || n->equals(scope.engine->id_destroy()) || n->equals(scope.engine->id_toString())) { if (p) { // ### probably not the fastest implementation @@ -942,7 +939,7 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E QQmlData *ddata = QQmlData::get(qobj, false); if (!ddata || !ddata->propertyCache) { QQmlPropertyData local; - QQmlPropertyData *property = QQmlPropertyCache::property(engine->jsEngine(), qobj, name, qmlContext, &local); + QQmlPropertyData *property = QQmlPropertyCache::property(qobj, name, qmlContext, &local); return property ? getProperty(engine, qobj, property) : QV4::Encode::undefined(); } QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobj, qmlContext); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index f3618d651e..eaa4783998 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -202,11 +202,11 @@ protected: static ReturnedValue create(ExecutionEngine *engine, QObject *object); static QQmlPropertyData *findProperty( - ExecutionEngine *engine, QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext, + QObject *o, const QQmlRefPointer<QQmlContextData> &qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local); QQmlPropertyData *findProperty( - ExecutionEngine *engine, const QQmlRefPointer<QQmlContextData> &qmlContext, + const QQmlRefPointer<QQmlContextData> &qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const; static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty); diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 4efda0f5d5..59922be564 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -847,8 +847,7 @@ static bool initObjectLookup( QQmlPropertyData *property; if (!ddata->propertyCache) { - property = QQmlPropertyCache::property( - aotContext->engine, object, name, aotContext->qmlContext, nullptr); + property = QQmlPropertyCache::property(object, name, aotContext->qmlContext, nullptr); } else { property = ddata->propertyCache->property( name.getPointer(), object, aotContext->qmlContext); diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 5821aca595..69e37eb1dd 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -358,8 +358,7 @@ static bool readObjectProperty( QVariant *target) { QQmlPropertyData local; - if (QQmlPropertyData *property = - QQmlPropertyCache::property(data->engine(), object, name, data, &local)) { + if (QQmlPropertyData *property = QQmlPropertyCache::property(object, name, data, &local)) { *target = object->metaObject()->property(property->coreIndex()).read(object); return true; } diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 62671f9e63..c9c913e4f5 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -281,13 +281,12 @@ public: static inline void flushPendingBinding(QObject *object, int coreIndex); void flushPendingBinding(int coreIndex); - static QQmlRefPointer<QQmlPropertyCache> ensurePropertyCache(QJSEngine *engine, QObject *object) + static QQmlRefPointer<QQmlPropertyCache> ensurePropertyCache(QObject *object) { - Q_ASSERT(engine); QQmlData *ddata = QQmlData::get(object, /*create*/true); if (Q_LIKELY(ddata->propertyCache)) return ddata->propertyCache; - return createPropertyCache(engine, object); + return createPropertyCache(object); } Q_ALWAYS_INLINE static uint offsetForBit(int bit) { return static_cast<uint>(bit) / BitsPerType; } @@ -298,8 +297,7 @@ private: mutable QQmlDataExtended *extendedData; Q_NEVER_INLINE static QQmlData *createQQmlData(QObjectPrivate *priv); - Q_NEVER_INLINE static QQmlRefPointer<QQmlPropertyCache> createPropertyCache( - QJSEngine *engine, QObject *object); + Q_NEVER_INLINE static QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QObject *object); Q_ALWAYS_INLINE bool hasBitSet(int bit) const { diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 6b5e2cf53a..8679e2a7b3 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1360,10 +1360,10 @@ QQmlData *QQmlData::createQQmlData(QObjectPrivate *priv) return static_cast<QQmlData *>(priv->declarativeData); } -QQmlRefPointer<QQmlPropertyCache> QQmlData::createPropertyCache(QJSEngine *engine, QObject *object) +QQmlRefPointer<QQmlPropertyCache> QQmlData::createPropertyCache(QObject *object) { QQmlData *ddata = QQmlData::get(object, /*create*/true); - ddata->propertyCache = QJSEnginePrivate::get(engine)->cache(object, QTypeRevision {}); + ddata->propertyCache = QQmlMetaType::propertyCache(object, QTypeRevision {}); return ddata->propertyCache; } @@ -1814,7 +1814,7 @@ QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type) type.createProxy(o); // if this object can use a property cache, create it now - QQmlData::ensurePropertyCache(q, o); + QQmlData::ensurePropertyCache(o); // even though the object is defined in C++, qmlContext(obj) and qmlEngine(obj) // should behave identically to QML singleton types. You can, however, manually diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index e9e4aeda4b..ca39db0ff0 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -208,8 +208,6 @@ public: // These methods may be called from any thread QString offlineStorageDatabaseDirectory() const; - using QJSEnginePrivate::cache; - // These methods may be called from the loader thread QQmlMetaObject rawMetaObjectForType(QMetaType metaType) const; QQmlMetaObject metaObjectForType(QMetaType metaType) const; diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp index 5f2cc2d44a..94888c7d7c 100644 --- a/src/qml/qml/qqmllist.cpp +++ b/src/qml/qml/qqmllist.cpp @@ -171,7 +171,7 @@ QQmlListReference::QQmlListReference(QObject *object, const char *property, QQml QQmlPropertyData local; QQmlPropertyData *data = - QQmlPropertyCache::property(engine, object, QLatin1String(property), nullptr, &local); + QQmlPropertyCache::property(object, QLatin1String(property), nullptr, &local); if (!data || !data->isQList()) return; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 44c005c2da..8c68b438f8 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1279,6 +1279,19 @@ QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileI return QQmlType(); } +/*! +Returns a QQmlPropertyCache for \a obj if one is available. + +If \a obj is null, being deleted or contains a dynamic meta object, +nullptr is returned. +*/ +QQmlRefPointer<QQmlPropertyCache> QQmlMetaType::propertyCache(QObject *obj, QTypeRevision version) +{ + if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) + return QQmlRefPointer<QQmlPropertyCache>(); + return QQmlMetaType::propertyCache(obj->metaObject(), version); +} + QQmlRefPointer<QQmlPropertyCache> QQmlMetaType::propertyCache( const QMetaObject *metaObject, QTypeRevision version) { diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 57e5ece326..ffd654c30c 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -174,6 +174,8 @@ public: static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); static QQmlRefPointer<QQmlPropertyCache> propertyCache( + QObject *object, QTypeRevision version = QTypeRevision()); + static QQmlRefPointer<QQmlPropertyCache> propertyCache( const QMetaObject *metaObject, QTypeRevision version = QTypeRevision()); static QQmlRefPointer<QQmlPropertyCache> propertyCache( const QQmlType &type, QTypeRevision version); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 9046cc26a0..950e3b1bd2 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -326,7 +326,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name, QQmlPropertyData local; QQmlPropertyData *property = currentObject - ? QQmlPropertyCache::property(engine, currentObject, pathName, context, &local) + ? QQmlPropertyCache::property(currentObject, pathName, context, &local) : nullptr; if (!property) { diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 9b01b2d8fb..cc5d9e11ac 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -896,8 +896,8 @@ static inline QByteArray qQmlPropertyCacheToString(const QV4::String *string) template<typename T> QQmlPropertyData * -qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name, - const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData *local) +qQmlPropertyCacheProperty(QObject *obj, T name, const QQmlRefPointer<QQmlContextData> &context, + QQmlPropertyData *local) { QQmlPropertyCache *cache = nullptr; @@ -905,13 +905,10 @@ qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name, if (ddata && ddata->propertyCache) { cache = ddata->propertyCache.data(); - } else if (engine) { - QJSEnginePrivate *ep = QJSEnginePrivate::get(engine); - if (auto newCache = ep->cache(obj)) { - cache = newCache.data(); - ddata = QQmlData::get(obj, true); - ddata->propertyCache = std::move(newCache); - } + } else if (auto newCache = QQmlMetaType::propertyCache(obj)) { + cache = newCache.data(); + ddata = QQmlData::get(obj, true); + ddata->propertyCache = std::move(newCache); } QQmlPropertyData *rv = nullptr; @@ -927,25 +924,25 @@ qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name, return rv; } -QQmlPropertyData * -QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QV4::String *name, - const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData *local) +QQmlPropertyData *QQmlPropertyCache::property( + QObject *obj, const QV4::String *name, const QQmlRefPointer<QQmlContextData> &context, + QQmlPropertyData *local) { - return qQmlPropertyCacheProperty<const QV4::String *>(engine, obj, name, context, local); + return qQmlPropertyCacheProperty<const QV4::String *>(obj, name, context, local); } -QQmlPropertyData * -QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, QStringView name, - const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData *local) +QQmlPropertyData *QQmlPropertyCache::property( + QObject *obj, QStringView name, const QQmlRefPointer<QQmlContextData> &context, + QQmlPropertyData *local) { - return qQmlPropertyCacheProperty<const QStringView &>(engine, obj, name, context, local); + return qQmlPropertyCacheProperty<const QStringView &>(obj, name, context, local); } -QQmlPropertyData * -QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QLatin1String &name, - const QQmlRefPointer<QQmlContextData> &context, QQmlPropertyData *local) +QQmlPropertyData *QQmlPropertyCache::property( + QObject *obj, const QLatin1String &name, const QQmlRefPointer<QQmlContextData> &context, + QQmlPropertyData *local) { - return qQmlPropertyCacheProperty<const QLatin1String &>(engine, obj, name, context, local); + return qQmlPropertyCacheProperty<const QLatin1String &>(obj, name, context, local); } // this function is copied from qmetaobject.cpp diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 46ecd0b5d2..68830ba716 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -213,12 +213,15 @@ public: inline QQmlPropertyData *overrideData(QQmlPropertyData *) const; inline bool isAllowedInRevision(QQmlPropertyData *) const; - static QQmlPropertyData *property(QJSEngine *, QObject *, QStringView, - const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData *); - static QQmlPropertyData *property(QJSEngine *, QObject *, const QLatin1String &, - const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData *); - static QQmlPropertyData *property(QJSEngine *, QObject *, const QV4::String *, - const QQmlRefPointer<QQmlContextData> &, QQmlPropertyData *); + static QQmlPropertyData *property( + QObject *, QStringView, const QQmlRefPointer<QQmlContextData> &, + QQmlPropertyData *); + static QQmlPropertyData *property( + QObject *, const QLatin1String &, const QQmlRefPointer<QQmlContextData> &, + QQmlPropertyData *); + static QQmlPropertyData *property( + QObject *, const QV4::String *, const QQmlRefPointer<QQmlContextData> &, + QQmlPropertyData *); //see QMetaObjectPrivate::originalClone int originalClone(int index); |