diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-15 13:27:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-16 19:05:40 +0000 |
commit | f2c97b4e307a62b831f68a0278551d4375170336 (patch) | |
tree | e4cfa8d09551f3fe6684c3b874357a633b7e0523 /src/qml/compiler | |
parent | 12d2b60218542e900076aebfce73a229a8b29ae1 (diff) |
PropertyCacheCreator traversal cleanup
Replace the direct linked list object traversal with iterators. This
will allow for re-use of the code against the QV4::CompiledData
structures when they get the same interface.
Change-Id: I901fd3377ef0f0317e5d9278cface37d80f93abf
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 34 | ||||
-rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator.cpp | 42 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 7 |
4 files changed, 68 insertions, 25 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index ce879a874a..4fa63e3c84 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -911,6 +911,16 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) f->location.column = loc.startColumn; f->index = index; f->nameIndex = registerString(funDecl->name.toString()); + + int formalsCount = 0; + for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next) + ++formalsCount; + f->formals.allocate(pool, formalsCount); + + int i = 0; + for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next, ++i) + f->formals[i] = registerString(it->name.toString()); + _object->appendFunction(f); } else { recordError(node->firstSourceLocation(), QCoreApplication::translate("QQmlParser","JavaScript declaration outside Script element")); diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 2409050f7d..a29727fc9e 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -175,6 +175,14 @@ struct PoolList return ptr; } + T &operator*() { + return *ptr; + } + + const T &operator*() const { + return *ptr; + } + void operator++() { ptr = ptr->next; } @@ -204,6 +212,12 @@ public: , count(0) {} + void allocate(QQmlJS::MemoryPool *pool, int size) + { + count = size; + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + } + void allocate(QQmlJS::MemoryPool *pool, const QVector<T> &vector) { count = vector.count(); @@ -244,6 +258,9 @@ public: return i; return -1; } + + const T *begin() const { return data; } + const T *end() const { return data + count; } }; struct Object; @@ -261,6 +278,10 @@ struct Signal QStringList parameterStringList(const QV4::Compiler::StringTableGenerator *stringPool) const; + int parameterCount() const { return parameters->count; } + PoolList<SignalParameter>::Iterator parametersBegin() const { return parameters->begin(); } + PoolList<SignalParameter>::Iterator parametersEnd() const { return parameters->end(); } + Signal *next; }; @@ -290,6 +311,13 @@ struct Function QV4::CompiledData::Location location; int nameIndex; quint32 index; // index in parsedQML::functions + FixedPoolArray<int> formals; + + // --- QQmlPropertyCacheCreator interface + const int *formalsBegin() const { return formals.begin(); } + const int *formalsEnd() const { return formals.end(); } + // --- + Function *next; }; @@ -342,6 +370,12 @@ public: PoolList<Binding>::Iterator bindingsEnd() const { return bindings->end(); } PoolList<Property>::Iterator propertiesBegin() const { return properties->begin(); } PoolList<Property>::Iterator propertiesEnd() const { return properties->end(); } + PoolList<Alias>::Iterator aliasesBegin() const { return aliases->begin(); } + PoolList<Alias>::Iterator aliasesEnd() const { return aliases->end(); } + PoolList<Signal>::Iterator signalsBegin() const { return qmlSignals->begin(); } + PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); } + PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); } + PoolList<Function>::Iterator functionsEnd() const { return functions->end(); } // If set, then declarations for this object (and init bindings for these) should go into the // specified object. Used for declarations inside group properties. diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp index 5e696652bd..a0bcba01ce 100644 --- a/src/qml/compiler/qqmlpropertycachecreator.cpp +++ b/src/qml/compiler/qqmlpropertycachecreator.cpp @@ -104,7 +104,7 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object bool needVMEMetaObject = obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0; if (!needVMEMetaObject) { - for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { + for (auto binding = obj->bindingsBegin(), end = obj->bindingsEnd(); binding != end; ++binding) { if (binding->type == QV4::CompiledData::Binding::Type_Object && (binding->flags & QV4::CompiledData::Binding::IsOnAssignment)) { // If the on assignment is inside a group property, we need to distinguish between QObject based // group properties and value type group properties. For the former the base type is derived from @@ -148,9 +148,9 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object } if (QQmlPropertyCache *thisCache = propertyCaches.at(objectIndex)) { - for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) + for (auto binding = obj->bindingsBegin(), end = obj->bindingsEnd(); binding != end; ++binding) if (binding->type >= QV4::CompiledData::Binding::Type_Object) { - InstantiationContext context(objectIndex, binding, stringAt(binding->propertyNameIndex), thisCache); + InstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache); QQmlCompileError error = buildMetaObjectRecursively(binding->value.objectIndex, context); if (error.isSet()) return error; @@ -280,7 +280,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con QmlIR::PropertyResolver resolver(baseTypeCache); - for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) { + for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p) { if (p->type == QV4::CompiledData::Property::Var) varPropCount++; @@ -290,7 +290,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con return QQmlCompileError(p->location, tr("Cannot override FINAL property")); } - for (const QmlIR::Alias *a = obj->firstAlias(); a; a = a->next) { + for (auto a = obj->aliasesBegin(), end = obj->aliasesEnd(); a != end; ++a) { bool notInRevision = false; QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex), ¬InRevision); if (d && d->isFinal()) @@ -324,7 +324,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con } // Set up notify signals for properties - first normal, then alias - for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) { + for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p) { quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMESignal; @@ -334,7 +334,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con cache->appendSignal(changedSigName, flags, effectiveMethodIndex++); } - for (const QmlIR::Alias *a = obj->firstAlias(); a; a = a->next) { + for (auto a = obj->aliasesBegin(), end = obj->aliasesEnd(); a != end; ++a) { quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMESignal; @@ -345,8 +345,8 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con } // Dynamic signals - for (const QmlIR::Signal *s = obj->firstSignal(); s; s = s->next) { - const int paramCount = s->parameters->count; + for (auto s = obj->signalsBegin(), end = obj->signalsEnd(); s != end; ++s) { + const int paramCount = s->parameterCount(); QList<QByteArray> names; names.reserve(paramCount); @@ -355,8 +355,8 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con if (paramCount) { paramTypes[0] = paramCount; - QmlIR::SignalParameter *param = s->parameters->first; - for (int i = 0; i < paramCount; ++i, param = param->next) { + int i = 0; + for (auto param = s->parametersBegin(), end = s->parametersEnd(); param != end; ++param, ++i) { names.append(stringAt(param->nameIndex).toUtf8()); if (param->type < builtinTypeCount) { // built-in type @@ -402,25 +402,19 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con // Dynamic slots - for (const QmlIR::Function *s = obj->firstFunction(); s; s = s->next) { - QQmlJS::AST::FunctionDeclaration *astFunction = s->functionDeclaration; - + for (auto function = compiler->objectFunctionsBegin(obj), end = compiler->objectFunctionsEnd(obj); function != end; ++function) { quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction; - if (astFunction->formals) - flags |= QQmlPropertyData::HasArguments; - - QString slotName = astFunction->name.toString(); + const QString slotName = stringAt(function->nameIndex); if (seenSignals.contains(slotName)) - return QQmlCompileError(s->location, tr("Duplicate method name: invalid override of property change signal or superclass signal")); + return QQmlCompileError(function->location, tr("Duplicate method name: invalid override of property change signal or superclass signal")); // Note: we don't append slotName to the seenSignals list, since we don't // protect against overriding change signals or methods with properties. QList<QByteArray> parameterNames; - QQmlJS::AST::FormalParameterList *param = astFunction->formals; - while (param) { - parameterNames << param->name.toUtf8(); - param = param->next; + for (auto formal = function->formalsBegin(), end = function->formalsEnd(); formal != end; ++formal) { + flags |= QQmlPropertyData::HasArguments; + parameterNames << stringAt(*formal).toUtf8(); } cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames); @@ -430,7 +424,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con // Dynamic properties int effectiveSignalIndex = cache->signalHandlerIndexCacheStart; int propertyIdx = 0; - for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) { + for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p, ++propertyIdx) { int propertyType = 0; quint32 propertyFlags = 0; diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 1e01f72228..351c4f7294 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -80,12 +80,17 @@ struct QQmlTypeCompiler public: QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document); + // --- interface used by QQmlPropertyCacheCreator + QString stringAt(int idx) const; + QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); } + QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); } + // --- + QV4::CompiledData::CompilationUnit *compile(); QList<QQmlError> compilationErrors() const { return errors; } void recordError(const QQmlError &error); - QString stringAt(int idx) const; int registerString(const QString &str); QV4::IR::Module *jsIRModule() const; |