diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4estable.cpp | 23 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4estable_p.h | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sparsearray_p.h | 44 | ||||
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 52 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 16 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 15 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata_p.h | 10 |
10 files changed, 102 insertions, 86 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 1452027dcb..3d7fc92a30 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -1334,14 +1334,14 @@ struct TypeReferenceMap : QHash<int, TypeReference> if (!formal->type.indexIsBuiltinType()) { TypeReference &r = this->add(formal->type.typeNameIndexOrBuiltinType(), it->location); - r.errorWhenNotFound = true; + r.errorWhenNotFound = false; } } if (!it->returnType.indexIsBuiltinType()) { TypeReference &r = this->add(it->returnType.typeNameIndexOrBuiltinType(), it->location); - r.errorWhenNotFound = true; + r.errorWhenNotFound = false; } } } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index b303dd497a..964bb78d3a 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2497,16 +2497,15 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi return true; } - if (metaType == QMetaType::fromType<QQmlListReference>()) { - if (const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) { + if (const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) { + if (metaType == QMetaType::fromType<QQmlListReference>()) { *reinterpret_cast<QQmlListReference *>(data) = wrapper->toListReference(); return true; } - } - if (metaType == QMetaType::fromType<QQmlListProperty<QObject>>()) { - if (const QV4::QmlListWrapper *wrapper = value.as<QV4::QmlListWrapper>()) { - *reinterpret_cast<QQmlListProperty<QObject> *>(data) = wrapper->d()->property(); + const auto wrapperPrivate = wrapper->d(); + if (QMetaType(wrapperPrivate->propertyType) == metaType) { + *reinterpret_cast<QQmlListProperty<QObject> *>(data) = wrapperPrivate->property(); return true; } } diff --git a/src/qml/jsruntime/qv4estable.cpp b/src/qml/jsruntime/qv4estable.cpp index 99f6bf6aa0..2e504a70cb 100644 --- a/src/qml/jsruntime/qv4estable.cpp +++ b/src/qml/jsruntime/qv4estable.cpp @@ -147,21 +147,18 @@ ReturnedValue ESTable::get(const Value &key, bool *hasValue) const // Removes the given \a key from the table bool ESTable::remove(const Value &key) { - bool found = false; - uint idx = 0; - for (; idx < m_size; ++idx) { - if (m_keys[idx].sameValueZero(key)) { - found = true; - break; + for (uint index = 0; index < m_size; ++index) { + if (m_keys[index].sameValueZero(key)) { + // Remove the element at |index| by moving all elements to the right + // of |index| one place to the left. + size_t count = (m_size - (index + 1)) * sizeof(Value); + memmove(m_keys + index, m_keys + index + 1, count); + memmove(m_values + index, m_values + index + 1, count); + m_size--; + return true; } } - - if (found == true) { - memmove(m_keys + idx, m_keys + idx + 1, (m_size - idx)*sizeof(Value)); - memmove(m_values + idx, m_values + idx + 1, (m_size - idx)*sizeof(Value)); - m_size--; - } - return found; + return false; } // Returns the size of the table. Note that the size may not match the underlying allocation. diff --git a/src/qml/jsruntime/qv4estable_p.h b/src/qml/jsruntime/qv4estable_p.h index f54fc37a7b..e63dda7a4d 100644 --- a/src/qml/jsruntime/qv4estable_p.h +++ b/src/qml/jsruntime/qv4estable_p.h @@ -53,12 +53,13 @@ #include "qv4value_p.h" +class tst_qv4estable; + QT_BEGIN_NAMESPACE -namespace QV4 -{ +namespace QV4 { -class ESTable +class Q_AUTOTEST_EXPORT ESTable { public: ESTable(); @@ -76,13 +77,15 @@ public: void removeUnmarkedKeys(); private: + friend class ::tst_qv4estable; + Value *m_keys = nullptr; Value *m_values = nullptr; uint m_size = 0; uint m_capacity = 0; }; -} +} // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h index 248fcdb02f..daa21baf06 100644 --- a/src/qml/jsruntime/qv4sparsearray_p.h +++ b/src/qml/jsruntime/qv4sparsearray_p.h @@ -146,8 +146,8 @@ struct Q_QML_EXPORT SparseArray { SparseArray(); ~SparseArray() { - if (root()) - freeTree(header.left, alignof(SparseArrayNode)); + if (SparseArrayNode *n = root()) + freeTree(n, alignof(SparseArrayNode)); } SparseArray(const SparseArray &other); @@ -323,37 +323,45 @@ inline QList<int> SparseArray::keys() const inline const SparseArrayNode *SparseArray::lowerBound(uint akey) const { - const SparseArrayNode *lb = root()->lowerBound(akey); - if (!lb) - lb = end(); - return lb; + if (SparseArrayNode *n = root()) { + if (const SparseArrayNode *lb = n->lowerBound(akey)) + return lb; + } + + return end(); } inline SparseArrayNode *SparseArray::lowerBound(uint akey) { - SparseArrayNode *lb = root()->lowerBound(akey); - if (!lb) - lb = end(); - return lb; + if (SparseArrayNode *n = root()) { + if (SparseArrayNode *lb = n->lowerBound(akey)) + return lb; + } + + return end(); } inline const SparseArrayNode *SparseArray::upperBound(uint akey) const { - const SparseArrayNode *ub = root()->upperBound(akey); - if (!ub) - ub = end(); - return ub; + if (SparseArrayNode *n = root()) { + if (const SparseArrayNode *ub = n->upperBound(akey)) + return ub; + } + + return end(); } inline SparseArrayNode *SparseArray::upperBound(uint akey) { - SparseArrayNode *ub = root()->upperBound(akey); - if (!ub) - ub = end(); - return ub; + if (SparseArrayNode *n = root()) { + if (SparseArrayNode *ub = n->upperBound(akey)) + return ub; + } + + return end(); } } diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index 5fb14332ab..8989efe701 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -251,7 +251,7 @@ struct QV4QPointer { private: QtSharedPointer::ExternalRefCountData *d; - QObject *qObject; + T *qObject; }; Q_STATIC_ASSERT(std::is_trivial< QV4QPointer<QObject> >::value); #endif diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 127fdf7ebb..ec596c0506 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -697,7 +697,13 @@ void qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>( QQmlEngine *AOTCompiledContext::qmlEngine() const { - return qmlContext ? qmlContext->engine() : nullptr; + return engine->handle()->qmlEngine(); +} + +static QQmlPropertyCapture *propertyCapture(const AOTCompiledContext *aotContext) +{ + QQmlEngine *engine = aotContext->qmlEngine(); + return engine ? QQmlEnginePrivate::get(aotContext->qmlEngine())->propertyCapture : nullptr; } QJSValue AOTCompiledContext::jsMetaType(int index) const @@ -722,31 +728,23 @@ void AOTCompiledContext::setReturnValueUndefined() const static void captureFallbackProperty( QObject *object, int coreIndex, int notifyIndex, bool isConstant, - QQmlContextData *qmlContext) + const AOTCompiledContext *aotContext) { - if (!qmlContext || isConstant) + if (isConstant) return; - QQmlEngine *engine = qmlContext->engine(); - Q_ASSERT(engine); - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - Q_ASSERT(ep); - if (QQmlPropertyCapture *capture = ep->propertyCapture) + if (QQmlPropertyCapture *capture = propertyCapture(aotContext)) capture->captureProperty(object, coreIndex, notifyIndex); } static void captureObjectProperty( QObject *object, const QQmlPropertyCache *propertyCache, - const QQmlPropertyData *property, QQmlContextData *qmlContext) + const QQmlPropertyData *property, const AOTCompiledContext *aotContext) { - if (!qmlContext || property->isConstant()) + if (property->isConstant()) return; - QQmlEngine *engine = qmlContext->engine(); - Q_ASSERT(engine); - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - Q_ASSERT(ep); - if (QQmlPropertyCapture *capture = ep->propertyCapture) + if (QQmlPropertyCapture *capture = propertyCapture(aotContext)) capture->captureProperty(object, propertyCache, property); } @@ -762,7 +760,7 @@ static bool inherits(const QQmlPropertyCache *descendent, const QQmlPropertyCach enum class ObjectPropertyResult { OK, NeedsInit, Deleted }; static ObjectPropertyResult loadObjectProperty( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { QQmlData *qmlData = QQmlData::get(object); if (!qmlData) @@ -779,13 +777,13 @@ static ObjectPropertyResult loadObjectProperty( if (qmlData->hasPendingBindingBit(coreIndex)) qmlData->flushPendingBinding(coreIndex); - captureObjectProperty(object, propertyCache, property, qmlContext); + captureObjectProperty(object, propertyCache, property, aotContext); property->readProperty(object, target); return ObjectPropertyResult::OK; } static ObjectPropertyResult loadFallbackProperty( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { QQmlData *qmlData = QQmlData::get(object); if (qmlData && qmlData->isQueuedForDeletion) @@ -803,7 +801,7 @@ static ObjectPropertyResult loadFallbackProperty( qmlData->flushPendingBinding(coreIndex); captureFallbackProperty(object, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, aotContext); void *a[] = { target, nullptr }; metaObject->metacall(object, QMetaObject::ReadProperty, coreIndex, a); @@ -984,7 +982,7 @@ bool AOTCompiledContext::captureLookup(uint index, QObject *object) const || l->getter == QV4::Lookup::getterQObject) { const QQmlPropertyData *property = l->qobjectLookup.propertyData; QQmlData::flushPendingBinding(object, property->coreIndex()); - captureObjectProperty(object, l->qobjectLookup.propertyCache, property, qmlContext); + captureObjectProperty(object, l->qobjectLookup.propertyCache, property, this); return true; } @@ -993,7 +991,7 @@ bool AOTCompiledContext::captureLookup(uint index, QObject *object) const QQmlData::flushPendingBinding(object, coreIndex); captureFallbackProperty( object, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, this); return true; } @@ -1007,7 +1005,7 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const && l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupContextObjectProperty) { const QQmlPropertyData *property = l->qobjectLookup.propertyData; QQmlData::flushPendingBinding(qmlScopeObject, property->coreIndex()); - captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, property, qmlContext); + captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, property, this); return true; } @@ -1015,7 +1013,7 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const const int coreIndex = l->qobjectFallbackLookup.coreIndex; QQmlData::flushPendingBinding(qmlScopeObject, coreIndex); captureFallbackProperty(qmlScopeObject, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, this); return true; } @@ -1267,9 +1265,9 @@ bool AOTCompiledContext::loadScopeObjectPropertyLookup(uint index, void *target) ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeObjectProperty) - result = loadObjectProperty(l, qmlScopeObject, target, qmlContext); + result = loadObjectProperty(l, qmlScopeObject, target, this); else if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeFallbackProperty) - result = loadFallbackProperty(l, qmlScopeObject, target, qmlContext); + result = loadFallbackProperty(l, qmlScopeObject, target, this); else return false; @@ -1405,9 +1403,9 @@ bool AOTCompiledContext::getObjectLookup(uint index, QObject *object, void *targ ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; if (l->getter == QV4::Lookup::getterQObject) - result = loadObjectProperty(l, object, target, qmlContext); + result = loadObjectProperty(l, object, target, this); else if (l->getter == QV4::Lookup::getterFallback) - result = loadFallbackProperty(l, object, target, qmlContext); + result = loadFallbackProperty(l, object, target, this); else return false; diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 372103b94f..d4a6ba1dd3 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -812,17 +812,21 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope oldBinding = data->bindings; while (oldBinding && (oldBinding->targetPropertyIndex().coreIndex() != coreIndex || - oldBinding->targetPropertyIndex().hasValueTypeIndex())) + oldBinding->targetPropertyIndex().hasValueTypeIndex())) { oldBinding = oldBinding->nextBinding(); + } - if (!oldBinding) - return; - - if (valueTypeIndex != -1 && oldBinding->isValueTypeProxy()) + if (valueTypeIndex != -1 + && oldBinding + && oldBinding->isValueTypeProxy()) { oldBinding = static_cast<QQmlValueTypeProxyBinding *>(oldBinding.data())->binding(index); + } - if (!oldBinding) + if (!oldBinding) { + // Clear the binding bit so that the binding doesn't appear later for any reason + data->clearBindingBit(coreIndex); return; + } if (!(flags & QQmlPropertyPrivate::DontEnable)) oldBinding->setEnabled(false, {}); diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index a244bdd0ba..2d2f37261c 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -345,7 +345,9 @@ void QQmlTypeData::done() ++it) { const TypeReference &type = *it; Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType()); - if (type.type.isInlineComponentType() && !type.type.pendingResolutionName().isEmpty()) { + if (type.errorWhenNotFound + && type.type.isInlineComponentType() + && !type.type.pendingResolutionName().isEmpty()) { auto containingType = type.type.containingType(); auto objectId = containingType.lookupInlineComponentIdByName(type.type.pendingResolutionName()); if (objectId < 0) { // can be any negative number if we tentatively resolved it in QQmlImport but it actually was not an inline component @@ -365,7 +367,7 @@ void QQmlTypeData::done() type.type.setInlineComponentObjectId(objectId); } } - if (type.typeData && type.typeData->isError()) { + if (type.errorWhenNotFound && type.typeData && type.typeData->isError()) { const QString typeName = stringAt(it.key()); QList<QQmlError> errors = type.typeData->errors(); @@ -887,6 +889,7 @@ void QQmlTypeData::resolveTypes() ref.version = version; ref.location = unresolvedRef->location; ref.needsCreation = unresolvedRef->needsCreation; + ref.errorWhenNotFound = unresolvedRef->errorWhenNotFound; m_resolvedTypes.insert(unresolvedRef.key(), ref); } @@ -930,8 +933,12 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches( } else { objectId = resolvedType->type.inlineComponentId(); } - Q_ASSERT(objectId != -1); - ref->setTypePropertyCache(resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId)); + + if (objectId >= 0) { + ref->setTypePropertyCache( + resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId)); + } + ref->setType(qmlType); Q_ASSERT(ref->type().isInlineComponentType()); } diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index 2c56ede9bd..e55e5ebae6 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -62,16 +62,16 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob public: struct TypeReference { - TypeReference() : version(QTypeRevision::zero()), needsCreation(true) {} - QV4::CompiledData::Location location; QQmlType type; - QTypeRevision version; + QTypeRevision version = QTypeRevision::zero(); QQmlRefPointer<QQmlTypeData> typeData; - bool selfReference = false; QString prefix; // used by CompositeSingleton types + bool selfReference = false; + bool needsCreation = true; + bool errorWhenNotFound = true; + QString qualifiedName() const; - bool needsCreation; }; struct ScriptReference |