From 9df65c172bc33774bad17da7f9cb66184578d49a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 6 Mar 2013 16:58:15 -0800 Subject: Backport some enum optimizations from Qt 5 Saving the int when we check the enum is valid allows us to make it a literal assignment instead of a binding, which is much faster on object creation. Change-Id: Ieb174289438a17574c4716df372b04d4dee6d0da Reviewed-by: Christopher Adams Reviewed-by: Alan Alpert --- src/declarative/qml/qdeclarativecompiler.cpp | 44 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'src/declarative') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 85ae3ebc..336e047d 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -326,10 +326,14 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.line = v->location.start.line; if (prop.isEnumType()) { int value; - if (prop.isFlagType()) { - value = prop.enumerator().keysToValue(string.toUtf8().constData()); - } else - value = prop.enumerator().keyToValue(string.toUtf8().constData()); + if (v->value.isNumber()) { //Number saved from earlier check - not valid in testLiteralAssignment + value = v->value.asNumber(); + } else { + if (prop.isFlagType()) + value = prop.enumerator().keysToValue(string.toUtf8().constData()); + else + value = prop.enumerator().keyToValue(string.toUtf8().constData()); + } instr.type = QDeclarativeInstruction::StoreInteger; instr.storeInteger.propertyIndex = prop.propertyIndex(); @@ -2203,6 +2207,12 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr return true; } +struct StaticQtMetaObject : public QObject +{ + static const QMetaObject *get() + { return &static_cast (0)->staticQtMetaObject; } +}; + bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Value *v, @@ -2235,20 +2245,32 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop objTypeName = objType->qmlTypeName(); } - if (!type || objTypeName != type->qmlTypeName()) + if (!type && typeName != QLatin1String("Qt")) return true; QString enumValue = parts.at(1); - int value; - if (prop.isFlagType()) { - value = prop.enumerator().keysToValue(enumValue.toUtf8().constData()); - } else - value = prop.enumerator().keyToValue(enumValue.toUtf8().constData()); + int value = -1; + + if (type && objTypeName == type->qmlTypeName()) { + if (prop.isFlagType()) { + value = prop.enumerator().keysToValue(enumValue.toUtf8().constData()); + } else { + value = prop.enumerator().keyToValue(enumValue.toUtf8().constData()); + } + } else { + QByteArray enumName = enumValue.toUtf8(); + //Special case for Qt object + const QMetaObject *metaObject = type ? type->metaObject() : StaticQtMetaObject::get(); + for (int ii = metaObject->enumeratorCount() - 1; value == -1 && ii >= 0; --ii) { + QMetaEnum e = metaObject->enumerator(ii); + value = e.keyToValue(enumName.constData()); + } + } if (value == -1) return true; v->type = Value::Literal; - v->value = QDeclarativeParser::Variant(enumValue); + v->value = QDeclarativeParser::Variant((double)value); *isAssignment = true; return true; -- cgit v1.2.3