diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2016-05-26 20:50:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-05-30 07:16:25 +0000 |
commit | d146b955f5be556e155441637c4dbf0920ef892b (patch) | |
tree | 1b25637512e87e783041394f061d9eece1822927 | |
parent | f27d058c11b54b3c5f72d41c25cb00657b49a37b (diff) |
Remove the custom parser binding bits hash table from QQmlCompiledData
Similary to the other hash tables we can store the actual information about
whether a binding is covered by a custom parser or not straight in the
CompiledData::Binding.
Change-Id: Iab9044af57338cec935d3ef38764d7dc1aa507e8
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 59 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 44 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 5 |
6 files changed, 66 insertions, 58 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 937ace2722..1f9e0e2752 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -203,8 +203,8 @@ bool QQmlTypeCompiler::compile() } { - QQmlDeferredBindingScanner deferredBindingScanner(this); - if (!deferredBindingScanner.scanObject()) + QQmlDeferredAndCustomParserBindingScanner deferredAndCustomParserBindingScanner(this); + if (!deferredAndCustomParserBindingScanner.scanObject()) return false; } @@ -352,11 +352,6 @@ const QQmlPropertyCacheVector &QQmlTypeCompiler::propertyCaches() const return compiledData->propertyCaches; } -QHash<int, QBitArray> *QQmlTypeCompiler::customParserBindings() -{ - return &compiledData->customParserBindings; -} - QQmlJS::MemoryPool *QQmlTypeCompiler::memoryPool() { return document->jsParserEngine.pool(); @@ -1662,20 +1657,21 @@ bool QQmlComponentAndAliasResolver::resolveAliases() return true; } -QQmlDeferredBindingScanner::QQmlDeferredBindingScanner(QQmlTypeCompiler *typeCompiler) +QQmlDeferredAndCustomParserBindingScanner::QQmlDeferredAndCustomParserBindingScanner(QQmlTypeCompiler *typeCompiler) : QQmlCompilePass(typeCompiler) , qmlObjects(typeCompiler->qmlObjects()) , propertyCaches(typeCompiler->propertyCaches()) + , customParsers(typeCompiler->customParserCache()) , _seenObjectWithId(false) { } -bool QQmlDeferredBindingScanner::scanObject() +bool QQmlDeferredAndCustomParserBindingScanner::scanObject() { return scanObject(compiler->rootObjectIndex()); } -bool QQmlDeferredBindingScanner::scanObject(int objectIndex) +bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) { QmlIR::Object *obj = qmlObjects->at(objectIndex); if (obj->idNameIndex != 0) @@ -1703,6 +1699,8 @@ bool QQmlDeferredBindingScanner::scanObject(int objectIndex) defaultProperty = propertyCache->defaultProperty(); } + QQmlCustomParser *customParser = customParsers.value(obj->inheritedTypeNameIndex); + QmlIR::PropertyResolver propertyResolver(propertyCache); QStringList deferredPropertyNames; @@ -1716,12 +1714,24 @@ bool QQmlDeferredBindingScanner::scanObject(int objectIndex) } for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) - continue; - QQmlPropertyData *pd = 0; QString name = stringAt(binding->propertyNameIndex); + + if (customParser) { + if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) { + binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; + continue; + } + } else if (QmlIR::IRBuilder::isSignalPropertyName(name) + && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) { + obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; + binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + continue; + } + } + if (name.isEmpty()) { pd = defaultProperty; name = defaultPropertyName; @@ -1733,9 +1743,6 @@ bool QQmlDeferredBindingScanner::scanObject(int objectIndex) pd = propertyResolver.property(name, ¬InRevision, QmlIR::PropertyResolver::CheckRevision); } - if (!pd) - continue; - bool seenSubObjectWithId = false; if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) { @@ -1753,6 +1760,17 @@ bool QQmlDeferredBindingScanner::scanObject(int objectIndex) binding->flags |= QV4::CompiledData::Binding::IsDeferredBinding; obj->flags |= QV4::CompiledData::Object::HasDeferredBindings; } + + if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression + || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) + continue; + + if (!pd) { + if (customParser) { + obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; + binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + } + } } return true; @@ -1766,7 +1784,6 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler) , resolvedTypes(*typeCompiler->resolvedTypes()) , customParsers(typeCompiler->customParserCache()) , propertyCaches(typeCompiler->propertyCaches()) - , customParserBindingsPerObject(typeCompiler->customParserBindings()) { } @@ -1850,8 +1867,6 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD groupProperties.insert(pos, binding); } - QBitArray customParserBindings(obj->nBindings); - QmlIR::PropertyResolver propertyResolver(propertyCache); QString defaultPropertyName; @@ -1875,13 +1890,11 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) { customBindings << binding; - customParserBindings.setBit(i); continue; } } else if (QmlIR::IRBuilder::isSignalPropertyName(name) && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) { customBindings << binding; - customParserBindings.setBit(i); continue; } } @@ -2018,7 +2031,6 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } else { if (customParser) { customBindings << binding; - customParserBindings.setBit(i); continue; } if (bindingToDefaultProperty) { @@ -2043,7 +2055,6 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD customParser->validator = 0; customParser->engine = 0; customParser->imports = (QQmlImports*)0; - customParserBindingsPerObject->insert(objectIndex, customParserBindings); const QList<QQmlError> parserErrors = customParser->errors(); if (!parserErrors.isEmpty()) { foreach (const QQmlError &error, parserErrors) diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 9cdac03896..64d2e6c925 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -103,7 +103,6 @@ public: const QQmlPropertyCacheVector &propertyCaches() const; void setComponentRoots(const QVector<quint32> &roots) { m_componentRoots = roots; } const QVector<quint32> &componentRoots() const { return m_componentRoots; } - QHash<int, QBitArray> *customParserBindings(); QQmlJS::MemoryPool *memoryPool(); QStringRef newStringRef(const QString &string); const QV4::Compiler::StringTableGenerator *stringPool() const; @@ -280,10 +279,10 @@ protected: QQmlPropertyCacheVector propertyCaches; }; -class QQmlDeferredBindingScanner : public QQmlCompilePass +class QQmlDeferredAndCustomParserBindingScanner : public QQmlCompilePass { public: - QQmlDeferredBindingScanner(QQmlTypeCompiler *typeCompiler); + QQmlDeferredAndCustomParserBindingScanner(QQmlTypeCompiler *typeCompiler); bool scanObject(); @@ -292,6 +291,7 @@ private: QList<QmlIR::Object*> *qmlObjects; QQmlPropertyCacheVector propertyCaches; + const QHash<int, QQmlCustomParser*> &customParsers; bool _seenObjectWithId; }; @@ -319,7 +319,6 @@ private: const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; const QHash<int, QQmlCustomParser*> &customParsers; const QQmlPropertyCacheVector &propertyCaches; - QHash<int, QBitArray> *customParserBindingsPerObject; // collected state variables, essentially write-only mutable QVector<QV4::CompiledData::BindingPropertyData> _bindingPropertyDataPerObject; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 08c4c65a1f..a9927f33a9 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -236,7 +236,8 @@ struct Q_QML_PRIVATE_EXPORT Binding IsResolvedEnum = 0x10, IsListItem = 0x20, IsBindingToAlias = 0x40, - IsDeferredBinding = 0x80 + IsDeferredBinding = 0x80, + IsCustomParserBinding = 0x100, }; quint32 flags : 16; @@ -396,7 +397,8 @@ struct Object enum Flags { NoFlag = 0x0, IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary - HasDeferredBindings = 0x2 // any of the bindings are deferred + HasDeferredBindings = 0x2, // any of the bindings are deferred + HasCustomParserBindings = 0x4 }; // Depending on the use, this may be the type name to instantiate before instantiating this diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index c4883a6279..60900f0185 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -131,8 +131,7 @@ public: QList<QQmlScriptData *> scripts; QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit; - // hash key is object index, value is indicies of bindings covered by custom parser - QHash<int, QBitArray> customParserBindings; + int totalBindingsCount; // Number of bindings used in this type int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses int totalObjectCount; // Number of objects explicitly instantiated diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0607e02173..e034ccb17f 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -255,7 +255,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) qSwap(_bindingTarget, bindingTarget); qSwap(_vmeMetaObject, vmeMetaObject); - setupBindings(/*binding skip list*/QBitArray(), /*applyDeferredBindings=*/true); + setupBindings(/*applyDeferredBindings=*/true); qSwap(_vmeMetaObject, vmeMetaObject); qSwap(_bindingTarget, bindingTarget); @@ -622,7 +622,7 @@ static QQmlType *qmlTypeForObject(QObject *object) return type; } -void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip, bool applyDeferredBindings) +void QQmlObjectCreator::setupBindings(bool applyDeferredBindings) { QQmlListProperty<void> savedList; qSwap(_currentList, savedList); @@ -673,7 +673,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip, bool appl const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable(); for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) { - if (static_cast<int>(i) < bindingsToSkip.size() && bindingsToSkip.testBit(i)) + if (binding->flags & QV4::CompiledData::Binding::IsCustomParserBinding) continue; if (binding->flags & QV4::CompiledData::Binding::IsDeferredBinding) { @@ -1125,24 +1125,22 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (isContextObject) context->contextObject = instance; - QBitArray bindingsToSkip; - if (customParser) { - QHash<int, QBitArray>::ConstIterator customParserBindings = compiledData->customParserBindings.constFind(index); - if (customParserBindings != compiledData->customParserBindings.constEnd()) { - customParser->engine = QQmlEnginePrivate::get(engine); - customParser->imports = compiledData->importCache; - - QList<const QV4::CompiledData::Binding *> bindings; - const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); - for (int i = 0; i < customParserBindings->count(); ++i) - if (customParserBindings->testBit(i)) - bindings << obj->bindingTable() + i; - customParser->applyBindings(instance, compiledData, bindings); - - customParser->engine = 0; - customParser->imports = (QQmlTypeNameCache*)0; - bindingsToSkip = *customParserBindings; + if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) { + customParser->engine = QQmlEnginePrivate::get(engine); + customParser->imports = compiledData->importCache; + + QList<const QV4::CompiledData::Binding *> bindings; + const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); + const QV4::CompiledData::Binding *binding = obj->bindingTable(); + for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) { + if (binding->flags & QV4::CompiledData::Binding::IsCustomParserBinding) { + bindings << binding; + } } + customParser->applyBindings(instance, compiledData, bindings); + + customParser->engine = 0; + customParser->imports = (QQmlTypeNameCache*)0; } if (isComponent) { @@ -1171,7 +1169,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo qSwap(_qmlContext, qmlContext); - bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0, bindingsToSkip); + bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0); qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); @@ -1266,7 +1264,7 @@ void QQmlObjectCreator::clear() phase = Done; } -bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty, const QBitArray &bindingsToSkip) +bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty) { QQmlData *declarativeData = QQmlData::get(instance, /*create*/true); @@ -1314,7 +1312,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * if (_compiledObject->nFunctions > 0) setupFunctions(); - setupBindings(bindingsToSkip); + setupBindings(); qSwap(_vmeMetaObject, vmeMetaObject); qSwap(_bindingTarget, bindingTarget); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index d0ed38334d..f51cf3a2ca 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -111,10 +111,9 @@ private: QObject *createInstance(int index, QObject *parent = 0, bool isContextObject = false); bool populateInstance(int index, QObject *instance, - QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty, - const QBitArray &bindingsToSkip = QBitArray()); + QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty); - void setupBindings(const QBitArray &bindingsToSkip, bool applyDeferredBindings = false); + void setupBindings(bool applyDeferredBindings = false); bool setPropertyBinding(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding); void setPropertyValue(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding); void setupFunctions(); |