aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/common/qv4compileddata_p.h4
-rw-r--r--src/qml/jsruntime/qv4engine.cpp11
-rw-r--r--src/qml/jsruntime/qv4estable.cpp23
-rw-r--r--src/qml/jsruntime/qv4estable_p.h11
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h44
-rw-r--r--src/qml/memory/qv4heap_p.h2
-rw-r--r--src/qml/qml/qqml.cpp52
-rw-r--r--src/qml/qml/qqmlproperty.cpp16
-rw-r--r--src/qml/qml/qqmltypedata.cpp15
-rw-r--r--src/qml/qml/qqmltypedata_p.h10
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