aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2016-05-26 20:50:44 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-05-30 07:16:25 +0000
commitd146b955f5be556e155441637c4dbf0920ef892b (patch)
tree1b25637512e87e783041394f061d9eece1822927
parentf27d058c11b54b3c5f72d41c25cb00657b49a37b (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.cpp59
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h6
-rw-r--r--src/qml/qml/qqmlcompiler_p.h3
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp44
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h5
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, &notInRevision, 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();