diff options
Diffstat (limited to 'src/qml/qml/qqmlcompiler.cpp')
-rw-r--r-- | src/qml/qml/qqmlcompiler.cpp | 202 |
1 files changed, 89 insertions, 113 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 9304a75fbf..51343b64d5 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -71,6 +71,7 @@ #include <QAtomicInt> #include <QtCore/qdebug.h> #include <QtCore/qdatetime.h> +#include <QtCore/qvarlengtharray.h> Q_DECLARE_METATYPE(QList<int>) Q_DECLARE_METATYPE(QList<qreal>) @@ -2830,32 +2831,37 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } } + // Size of the array that describes parameter types & names + int paramDataSize = (obj->aggregateDynamicSignalParameterCount() + obj->aggregateDynamicSlotParameterCount()) * 2 + + obj->dynamicProperties.count() // for Changed() signals return types + // Return "parameters" don't have names + - (obj->dynamicSignals.count() + obj->dynamicSlots.count()); + QFastMetaBuilder builder; + int paramIndex; QFastMetaBuilder::StringRef classNameRef = builder.init(newClassName.length(), obj->dynamicProperties.count() - (resolveAlias?0:aliasCount), obj->dynamicSlots.count(), obj->dynamicSignals.count() + obj->dynamicProperties.count(), - defaultProperty?1:0); + defaultProperty?1:0, paramDataSize, ¶mIndex); struct TypeData { Object::DynamicProperty::Type dtype; int metaType; - const char *cppType; } builtinTypes[] = { - { Object::DynamicProperty::Var, QMetaType::QVariant, "QVariant" }, - { Object::DynamicProperty::Variant, QMetaType::QVariant, "QVariant" }, - { Object::DynamicProperty::Int, QMetaType::Int, "int" }, - { Object::DynamicProperty::Bool, QMetaType::Bool, "bool" }, - { Object::DynamicProperty::Real, QMetaType::Double, "double" }, - { Object::DynamicProperty::String, QMetaType::QString, "QString" }, - { Object::DynamicProperty::Url, QMetaType::QUrl, "QUrl" }, - { Object::DynamicProperty::Color, QMetaType::QColor, "QColor" }, - { Object::DynamicProperty::Time, QMetaType::QTime, "QTime" }, - { Object::DynamicProperty::Date, QMetaType::QDate, "QDate" }, - { Object::DynamicProperty::DateTime, QMetaType::QDateTime, "QDateTime" }, + { Object::DynamicProperty::Var, QMetaType::QVariant }, + { Object::DynamicProperty::Variant, QMetaType::QVariant }, + { Object::DynamicProperty::Int, QMetaType::Int }, + { Object::DynamicProperty::Bool, QMetaType::Bool }, + { Object::DynamicProperty::Real, QMetaType::Double }, + { Object::DynamicProperty::String, QMetaType::QString }, + { Object::DynamicProperty::Url, QMetaType::QUrl }, + { Object::DynamicProperty::Color, QMetaType::QColor }, + { Object::DynamicProperty::Time, QMetaType::QTime }, + { Object::DynamicProperty::Date, QMetaType::QDate }, + { Object::DynamicProperty::DateTime, QMetaType::QDateTime }, }; static const int builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData); - QFastMetaBuilder::StringRef typeRefs[builtinTypeCount]; // Reserve dynamic properties if (obj->dynamicProperties.count()) { @@ -2868,18 +2874,16 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod if (p->type != Object::DynamicProperty::Alias || resolveAlias) p->nameRef = builder.newString(p->name.utf8length()); - int propertyType = 0; + int metaType = 0; + int propertyType = 0; // for VMD bool readonly = false; - QFastMetaBuilder::StringRef typeRef; if (p->type == Object::DynamicProperty::Alias) { continue; } else if (p->type < builtinTypeCount) { Q_ASSERT(builtinTypes[p->type].dtype == p->type); - propertyType = builtinTypes[p->type].metaType; - if (typeRefs[p->type].isEmpty()) - typeRefs[p->type] = builder.newString(strlen(builtinTypes[p->type].cppType)); - typeRef = typeRefs[p->type]; + metaType = builtinTypes[p->type].metaType; + propertyType = metaType; } else { Q_ASSERT(p->type == Object::DynamicProperty::CustomList || @@ -2915,9 +2919,9 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod propertyType = qMetaTypeId<QQmlListProperty<QObject> >(); } - p->resolvedCustomTypeName = pool->NewByteArray(customTypeName); - p->typeRef = builder.newString(customTypeName.length()); - typeRef = p->typeRef; + metaType = QMetaType::type(customTypeName); + Q_ASSERT(metaType != QMetaType::UnknownType); + Q_ASSERT(metaType != QMetaType::Void); } if (p->type == Object::DynamicProperty::Var) @@ -2932,17 +2936,13 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType; } - if (p->type < builtinTypeCount) - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)propertyType, - readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, - effectivePropertyIndex); - else - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, - readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, - effectivePropertyIndex); + builder.setProperty(effectivePropertyIndex, p->nameRef, metaType, + readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, + effectivePropertyIndex); - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; } @@ -2955,19 +2955,19 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod totalPropCount = varPropCount + effectivePropertyIndex; for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) { if (p->type == Object::DynamicProperty::Var) { - QFastMetaBuilder::StringRef typeRef = typeRefs[p->type]; if (buildData) { vmd->propertyCount++; (vmd->propertyData() + effectivePropertyIndex)->propertyType = QMetaType::QVariant; } - builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, + builder.setProperty(effectivePropertyIndex, p->nameRef, QMetaType::QVariant, p->isReadOnly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, effectivePropertyIndex); - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; } @@ -2986,8 +2986,9 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } // Even if we aren't resolving the alias, we need a fake signal so that the // metaobject remains consistent across the resolve and non-resolve alias runs - p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()")); - builder.setSignal(effectivePropertyIndex, p->changedSignatureRef); + p->changedNameRef = builder.newString(p->name.utf8length() + strlen("Changed")); + builder.setSignal(effectivePropertyIndex, p->changedNameRef, paramIndex); + paramIndex++; effectivePropertyIndex++; aliasIndex++; } @@ -3006,49 +3007,56 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod int signalIndex = 0; for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) { - int paramCount = s->parameterNames.count(); - - int signatureSize = s->name.utf8length() + 2 /* paren */; - int namesSize = 0; - if (paramCount) signatureSize += s->parameterTypesLength() + (paramCount - 1) /* commas */; - if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1) /* commas */; + s->nameRef = builder.newString(s->name.utf8length()); - s->signatureRef = builder.newString(signatureSize); - if (namesSize) s->parameterNamesRef = builder.newString(namesSize); + int paramCount = s->parameterNames.count(); + QVarLengthArray<int, 10> paramTypes(paramCount); + if (paramCount) { + s->parameterNamesRef = pool->NewRawList<QFastMetaBuilder::StringRef>(paramCount); + for (int i = 0; i < paramCount; ++i) { + s->parameterNamesRef[i] = builder.newString(s->parameterNames.at(i).utf8length()); + Q_ASSERT(s->parameterTypes.at(i) < builtinTypeCount); + paramTypes[i] = builtinTypes[s->parameterTypes.at(i)].metaType; + } + } if (buildData) ((QQmlVMEMetaData *)dynamicData.data())->signalCount++; - builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->signatureRef, s->parameterNamesRef); + builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->nameRef, + paramIndex, paramCount, paramTypes.constData(), s->parameterNamesRef.data()); + paramIndex += paramCount*2 + 1; ++signalIndex; } // Reserve dynamic slots if (obj->dynamicSlots.count()) { - // Allocate QVariant string - if (typeRefs[0].isEmpty()) - typeRefs[0] = builder.newString(strlen(builtinTypes[0].cppType)); - typedef QQmlVMEMetaData VMD; int methodIndex = 0; for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) { + s->nameRef = builder.newString(s->name.utf8length()); int paramCount = s->parameterNames.count(); - int signatureSize = s->name.utf8length() + 2 /* paren */; - int namesSize = 0; - if (paramCount) signatureSize += (paramCount * strlen("QVariant") + (paramCount - 1)); - if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); - - s->signatureRef = builder.newString(signatureSize); - if (namesSize) s->parameterNamesRef = builder.newString(namesSize); + QVarLengthArray<int, 10> paramTypes(paramCount); + if (paramCount) { + s->parameterNamesRef = pool->NewRawList<QFastMetaBuilder::StringRef>(paramCount); + for (int i = 0; i < paramCount; ++i) { + s->parameterNamesRef[i] = builder.newString(s->parameterNames.at(i).size()); + paramTypes[i] = QMetaType::QVariant; + } + } - builder.setMethod(methodIndex, s->signatureRef, s->parameterNamesRef, typeRefs[0]); + builder.setMethod(methodIndex, s->nameRef, paramIndex, paramCount, + paramTypes.constData(), s->parameterNamesRef.data(), QMetaType::QVariant); + paramIndex += paramCount*2 + 1; if (buildData) { QString funcScript; - funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + + int namesSize = 0; + if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); + funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + namesSize + 1 /* rparen */ + s->body.length() + 1 /* rparen */); funcScript = QLatin1String("(function ") + s->name.toString() + QLatin1Char('('); for (int jj = 0; jj < paramCount; ++jj) { @@ -3077,28 +3085,18 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod } } - // Now allocate used builtin types - for (int ii = 0; ii < builtinTypeCount; ++ii) { - if (!typeRefs[ii].isEmpty()) - typeRefs[ii].load(builtinTypes[ii].cppType); - } - // Now allocate properties for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) { - char *d = p->changedSignatureRef.data(); + char *d = p->changedNameRef.data(); p->name.writeUtf8(d); - strcpy(d + p->name.utf8length(), "Changed()"); + strcpy(d + p->name.utf8length(), "Changed"); + p->changedNameRef.loadByteArrayData(); if (p->type == Object::DynamicProperty::Alias && !resolveAlias) continue; p->nameRef.load(p->name); - - if (p->type >= builtinTypeCount) { - Q_ASSERT(p->resolvedCustomTypeName); - p->typeRef.load(*p->resolvedCustomTypeName); - } } // Allocate default property if necessary @@ -3108,39 +3106,18 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod // Now allocate signals for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) { - char *d = s->signatureRef.data(); - char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data(); - s->name.writeUtf8(d); d += s->name.utf8length(); - *d++ = '('; + s->nameRef.load(s->name); - for (int jj = 0; jj < s->parameterNames.count(); ++jj) { - if (jj != 0) { *d++ = ','; *d2++ = ','; } - strcpy(d, s->parameterTypes.at(jj).constData()); - d += s->parameterTypes.at(jj).length(); - s->parameterNames.at(jj).writeUtf8(d2); - d2 += s->parameterNames.at(jj).utf8length(); - } - *d++ = ')'; - *d = 0; - if (d2) *d2 = 0; + for (int jj = 0; jj < s->parameterNames.count(); ++jj) + s->parameterNamesRef[jj].load(s->parameterNames.at(jj)); } // Now allocate methods for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) { - char *d = s->signatureRef.data(); - char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data(); - s->name.writeUtf8(d); d += s->name.utf8length(); - *d++ = '('; - for (int jj = 0; jj < s->parameterNames.count(); ++jj) { - if (jj != 0) { *d++ = ','; *d2++ = ','; } - strcpy(d, "QVariant"); - d += strlen("QVariant"); - strcpy(d2, s->parameterNames.at(jj).constData()); - d2 += s->parameterNames.at(jj).length(); - } - *d++ = ')'; - *d = 0; - if (d2) *d2 = 0; + s->nameRef.load(s->name); + + for (int jj = 0; jj < s->parameterNames.count(); ++jj) + s->parameterNamesRef[jj].load(s->parameterNames.at(jj).constData()); } // Now allocate class name @@ -3233,7 +3210,6 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, Object::DynamicProperty &prop) { Q_ASSERT(!prop.nameRef.isEmpty()); - Q_ASSERT(prop.typeRef.isEmpty()); if (!prop.defaultValue) COMPILE_EXCEPTION(obj, tr("No property alias location")); @@ -3278,9 +3254,7 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, writable = aliasProperty.isWritable() && !prop.isReadOnly; resettable = aliasProperty.isResettable() && !prop.isReadOnly; - if (aliasProperty.type() < QVariant::UserType - || uint(aliasProperty.type()) == QMetaType::QVariant) - type = aliasProperty.type(); + type = aliasProperty.userType(); if (alias.count() == 3) { QQmlValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()]; @@ -3298,9 +3272,7 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, propIdx |= (valueTypeIndex << 16); // update the property type - type = aliasProperty.type(); - if (type >= (int)QVariant::UserType) - type = 0; + type = aliasProperty.userType(); } if (aliasProperty.isEnumType()) @@ -3322,22 +3294,26 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, if (typeName.endsWith('*')) flags |= QML_ALIAS_FLAG_PTR; + if (type == QMetaType::UnknownType) { + Q_ASSERT(!typeName.isEmpty()); + type = QMetaType::type(typeName); + Q_ASSERT(type != QMetaType::UnknownType); + Q_ASSERT(type != QMetaType::Void); + } + QQmlVMEMetaData::AliasData aliasData = { idObject->idIndex, propIdx, flags }; typedef QQmlVMEMetaData VMD; VMD *vmd = (QQmlVMEMetaData *)data.data(); *(vmd->aliasData() + aliasIndex) = aliasData; - prop.resolvedCustomTypeName = pool->NewByteArray(typeName); - prop.typeRef = builder.newString(typeName.length()); - int propertyFlags = 0; if (writable) propertyFlags |= QFastMetaBuilder::Writable; if (resettable) propertyFlags |= QFastMetaBuilder::Resettable; - builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type, + builder.setProperty(propIndex, prop.nameRef, type, (QFastMetaBuilder::PropertyFlag)propertyFlags, propIndex); |