From fcf9b7efa5b2a0d8f49e59b2a977b8122632aff6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 20 Jul 2018 15:19:17 +0200 Subject: Clean up constant storage for CompiledData::Binding Store doubles in bindings in the constant table of the compilation unit instead of each binding. This removes one of the two 8 byte members of the value union and also allows for sharing of constants throughout a .qml file. Change-Id: I1d7daafdb7f24e34c14cd160d2dcb2c5aaac1c50 Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlirbuilder.cpp | 4 +- src/qml/compiler/qqmlpropertyvalidator.cpp | 36 ++++++------- src/qml/compiler/qqmltypecompiler.cpp | 8 ++- src/qml/compiler/qqmltypecompiler_p.h | 1 + src/qml/compiler/qv4compileddata.cpp | 10 ++-- src/qml/compiler/qv4compileddata_p.h | 21 +++----- src/qml/qml/qqmlbinding.cpp | 2 +- src/qml/qml/qqmlobjectcreator.cpp | 68 ++++++++++++------------ src/qml/types/qqmllistmodel.cpp | 10 ++-- src/quick/util/qquickpropertychanges.cpp | 6 +-- tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp | 2 +- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 11 ++-- 12 files changed, 90 insertions(+), 89 deletions(-) diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 0461299866..1f6a702e4a 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1069,7 +1069,7 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST binding->value.b = false; } else if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast(expr)) { binding->type = QV4::CompiledData::Binding::Type_Number; - binding->setNumberValueInternal(lit->value); + binding->value.constantValueIndex = jsGenerator->registerConstant(QV4::Encode(lit->value)); } else if (QQmlJS::AST::CallExpression *call = QQmlJS::AST::cast(expr)) { if (QQmlJS::AST::IdentifierExpression *base = QQmlJS::AST::cast(call->base)) { tryGeneratingTranslationBinding(base->name, call->arguments, binding); @@ -1081,7 +1081,7 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST } else if (QQmlJS::AST::UnaryMinusExpression *unaryMinus = QQmlJS::AST::cast(expr)) { if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast(unaryMinus->expression)) { binding->type = QV4::CompiledData::Binding::Type_Number; - binding->setNumberValueInternal(-lit->value); + binding->value.constantValueIndex = jsGenerator->registerConstant(QV4::Encode(-lit->value)); } } } diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp index 7ae88cf80c..99bd525d47 100644 --- a/src/qml/compiler/qqmlpropertyvalidator.cpp +++ b/src/qml/compiler/qqmlpropertyvalidator.cpp @@ -333,7 +333,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) return noError; - QString value = binding->valueAsString(qmlUnit); + QString value = binding->valueAsString(compilationUnit.data()); QMetaProperty p = propertyCache->firstCppMetaObject()->property(property->coreIndex()); bool ok; if (p.isFlagType()) { @@ -376,7 +376,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::UInt: { if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double d = binding->valueAsNumber(); + double d = binding->valueAsNumber(compilationUnit->constants); if (double(uint(d)) == d) return noError; } @@ -385,7 +385,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::Int: { if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double d = binding->valueAsNumber(); + double d = binding->valueAsNumber(compilationUnit->constants); if (double(int(d)) == d) return noError; } @@ -406,7 +406,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::Color: { bool ok = false; - QQmlStringConverters::rgbaFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::rgbaFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: color expected")); } @@ -415,7 +415,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache #if QT_CONFIG(datestring) case QVariant::Date: { bool ok = false; - QQmlStringConverters::dateFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::dateFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: date expected")); } @@ -423,7 +423,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::Time: { bool ok = false; - QQmlStringConverters::timeFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::timeFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: time expected")); } @@ -431,7 +431,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::DateTime: { bool ok = false; - QQmlStringConverters::dateTimeFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::dateTimeFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: datetime expected")); } @@ -440,7 +440,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache #endif // datestring case QVariant::Point: { bool ok = false; - QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: point expected")); } @@ -448,7 +448,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::PointF: { bool ok = false; - QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: point expected")); } @@ -456,7 +456,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::Size: { bool ok = false; - QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: size expected")); } @@ -464,7 +464,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::SizeF: { bool ok = false; - QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: size expected")); } @@ -472,7 +472,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::Rect: { bool ok = false; - QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: rect expected")); } @@ -480,7 +480,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache break; case QVariant::RectF: { bool ok = false; - QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok); + QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok); if (!ok) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: point expected")); } @@ -497,7 +497,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache float xp; float yp; } vec; - if (!QQmlStringConverters::createFromString(QMetaType::QVector2D, binding->valueAsString(qmlUnit), &vec, sizeof(vec))) { + if (!QQmlStringConverters::createFromString(QMetaType::QVector2D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec))) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: 2D vector expected")); } } @@ -508,7 +508,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache float yp; float zy; } vec; - if (!QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(qmlUnit), &vec, sizeof(vec))) { + if (!QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec))) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: 3D vector expected")); } } @@ -520,7 +520,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache float zy; float wp; } vec; - if (!QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(qmlUnit), &vec, sizeof(vec))) { + if (!QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec))) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: 4D vector expected")); } } @@ -532,7 +532,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache float yp; float zp; } vec; - if (!QQmlStringConverters::createFromString(QMetaType::QQuaternion, binding->valueAsString(qmlUnit), &vec, sizeof(vec))) { + if (!QQmlStringConverters::createFromString(QMetaType::QQuaternion, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec))) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: quaternion expected")); } } @@ -549,7 +549,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache } else if (property->propType() == qMetaTypeId >()) { bool ok = (binding->type == QV4::CompiledData::Binding::Type_Number); if (ok) { - double n = binding->valueAsNumber(); + double n = binding->valueAsNumber(compilationUnit->constants); if (double(int(n)) != n) ok = false; } diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 6582a9ca6b..a6bdf93e2e 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -207,6 +207,11 @@ int QQmlTypeCompiler::registerString(const QString &str) return document->jsGenerator.registerString(str); } +int QQmlTypeCompiler::registerConstant(QV4::ReturnedValue v) +{ + return document->jsGenerator.registerConstant(v); +} + const QV4::CompiledData::Unit *QQmlTypeCompiler::qmlUnit() const { return document->javaScriptCompilationUnit->unitData(); @@ -555,7 +560,8 @@ bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, const QS COMPILE_EXCEPTION(binding, tr("Invalid property assignment: Enum value \"%1\" cannot start with a lowercase letter").arg(enumName.toString())); } binding->type = QV4::CompiledData::Binding::Type_Number; - binding->setNumberValueInternal((double)enumValue); + binding->value.constantValueIndex = compiler->registerConstant(QV4::Encode((double)enumValue)); +// binding->setNumberValueInternal((double)enumValue); binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum; return true; } diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 537f87ab4c..ffe04eb090 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -100,6 +100,7 @@ public: void recordError(const QQmlCompileError &error); int registerString(const QString &str); + int registerConstant(QV4::ReturnedValue v); const QV4::CompiledData::Unit *qmlUnit() const; diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index a4c7c98642..3e3859d9fb 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -588,7 +588,8 @@ void CompilationUnit::setUnitData(const Unit *unitData) #endif } -QString Binding::valueAsString(const Unit *unit) const +#ifndef V4_BOOTSTRAP +QString Binding::valueAsString(const CompilationUnit *unit) const { switch (type) { case Type_Script: @@ -597,7 +598,7 @@ QString Binding::valueAsString(const Unit *unit) const case Type_Boolean: return value.b ? QStringLiteral("true") : QStringLiteral("false"); case Type_Number: - return QString::number(valueAsNumber()); + return QString::number(valueAsNumber(unit->constants)); case Type_Invalid: return QString(); #if !QT_CONFIG(translation) @@ -611,7 +612,7 @@ QString Binding::valueAsString(const Unit *unit) const } case Type_Translation: { // This code must match that in the qsTr() implementation - const QString &path = unit->stringAt(unit->sourceFileIndex); + const QString &path = unit->stringAt(unit->data->sourceFileIndex); int lastSlash = path.lastIndexOf(QLatin1Char('/')); QStringRef context = (lastSlash > -1) ? path.midRef(lastSlash + 1, path.length() - lastSlash - 5) : QStringRef(); @@ -671,7 +672,7 @@ QString Binding::escapedString(const QString &string) return tmp; } -QString Binding::valueAsScriptString(const Unit *unit) const +QString Binding::valueAsScriptString(const CompilationUnit *unit) const { if (type == Type_String) return escapedString(unit->stringAt(stringIndex)); @@ -679,7 +680,6 @@ QString Binding::valueAsScriptString(const Unit *unit) const return valueAsString(unit); } -#ifndef V4_BOOTSTRAP /*! Returns the property cache, if one alread exists. The cache is not referenced. */ diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 31e83e8f76..7bbc4d2835 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -404,7 +404,7 @@ struct Q_QML_PRIVATE_EXPORT Binding }; union { bool b; - quint64 doubleValue; // do not access directly, needs endian protected access + quint32_le constantValueIndex; quint32_le compiledScriptIndex; // used when Type_Script quint32_le objectIndex; TranslationData translationData; // used when Type_Translation @@ -470,22 +470,15 @@ struct Q_QML_PRIVATE_EXPORT Binding bool isTranslationBinding() const { return type == Type_Translation || type == Type_TranslationById; } bool evaluatesToString() const { return type == Type_String || isTranslationBinding(); } - QString valueAsString(const Unit *unit) const; - QString valueAsScriptString(const Unit *unit) const; - double valueAsNumber() const +#ifndef V4_BOOTSTRAP + QString valueAsString(const CompilationUnit *unit) const; + QString valueAsScriptString(const CompilationUnit *unit) const; +#endif + double valueAsNumber(const Value *constantTable) const { if (type != Type_Number) return 0.0; - quint64 intval = qFromLittleEndian(value.doubleValue); - double d; - memcpy(&d, &intval, sizeof(double)); - return d; - } - void setNumberValueInternal(double d) - { - quint64 intval; - memcpy(&intval, &d, sizeof(double)); - value.doubleValue = qToLittleEndian(intval); + return constantTable[value.constantValueIndex].doubleValue(); } bool valueAsBoolean() const diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index a791497ad6..cf87d58e68 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -358,7 +358,7 @@ public: if (!isAddedToObject() || hasError()) return; - const QString result = m_binding->valueAsString(m_compilationUnit->unitData()); + const QString result = m_binding->valueAsString(m_compilationUnit.data()); Q_ASSERT(targetObject()); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 6f6065dc45..76f5d69c1a 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -373,7 +373,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const propertyType = QMetaType::Int; } else { // ### This should be resolved earlier at compile time and the binding value should be changed accordingly. - QVariant value = binding->valueAsString(qmlUnit); + QVariant value = binding->valueAsString(compilationUnit.data()); bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context); Q_ASSERT(ok); Q_UNUSED(ok); @@ -384,7 +384,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const switch (propertyType) { case QMetaType::QVariant: { if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double n = binding->valueAsNumber(); + double n = binding->valueAsNumber(compilationUnit->constants); if (double(int(n)) == n) { if (property->isVarProperty()) { _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Primitive::fromInt32(int(n))); @@ -409,7 +409,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const property->writeProperty(_qobject, &value, propertyWriteFlags); } } else { - QString stringValue = binding->valueAsString(qmlUnit); + QString stringValue = binding->valueAsString(compilationUnit.data()); if (property->isVarProperty()) { QV4::ScopedString s(scope, v4->newString(stringValue)); _vmeMetaObject->setVMEProperty(property->coreIndex(), s); @@ -422,25 +422,25 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::String: { Q_ASSERT(binding->evaluatesToString()); - QString value = binding->valueAsString(qmlUnit); + QString value = binding->valueAsString(compilationUnit.data()); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::StringList: { Q_ASSERT(binding->evaluatesToString()); - QStringList value(binding->valueAsString(qmlUnit)); + QStringList value(binding->valueAsString(compilationUnit.data())); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::ByteArray: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); - QByteArray value(binding->valueAsString(qmlUnit).toUtf8()); + QByteArray value(binding->valueAsString(compilationUnit.data()).toUtf8()); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Url: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); - QString string = binding->valueAsString(qmlUnit); + QString string = binding->valueAsString(compilationUnit.data()); // Encoded dir-separators defeat QUrl processing - decode them first string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); QUrl value = string.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(string)); @@ -452,7 +452,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::UInt: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); - double d = binding->valueAsNumber(); + double d = binding->valueAsNumber(compilationUnit->constants); uint value = uint(d); property->writeProperty(_qobject, &value, propertyWriteFlags); break; @@ -460,7 +460,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::Int: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); - double d = binding->valueAsNumber(); + double d = binding->valueAsNumber(compilationUnit->constants); int value = int(d); property->writeProperty(_qobject, &value, propertyWriteFlags); break; @@ -468,19 +468,19 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QMetaType::Float: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); - float value = float(binding->valueAsNumber()); + float value = float(binding->valueAsNumber(compilationUnit->constants)); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Double: { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); - double value = binding->valueAsNumber(); + double value = binding->valueAsNumber(compilationUnit->constants); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Color: { bool ok = false; - uint colorValue = QQmlStringConverters::rgbaFromString(binding->valueAsString(qmlUnit), &ok); + uint colorValue = QQmlStringConverters::rgbaFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); struct { void *data[4]; } buffer; if (QQml_valueTypeProvider()->storeValueType(property->propType(), &colorValue, &buffer, sizeof(buffer))) { @@ -491,21 +491,21 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const #if QT_CONFIG(datestring) case QVariant::Date: { bool ok = false; - QDate value = QQmlStringConverters::dateFromString(binding->valueAsString(qmlUnit), &ok); + QDate value = QQmlStringConverters::dateFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Time: { bool ok = false; - QTime value = QQmlStringConverters::timeFromString(binding->valueAsString(qmlUnit), &ok); + QTime value = QQmlStringConverters::timeFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::DateTime: { bool ok = false; - QDateTime value = QQmlStringConverters::dateTimeFromString(binding->valueAsString(qmlUnit), &ok); + QDateTime value = QQmlStringConverters::dateTimeFromString(binding->valueAsString(compilationUnit.data()), &ok); // ### VME compatibility :( { const qint64 date = value.date().toJulianDay(); @@ -519,42 +519,42 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const #endif // datestring case QVariant::Point: { bool ok = false; - QPoint value = QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok).toPoint(); + QPoint value = QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok).toPoint(); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::PointF: { bool ok = false; - QPointF value = QQmlStringConverters::pointFFromString(binding->valueAsString(qmlUnit), &ok); + QPointF value = QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Size: { bool ok = false; - QSize value = QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok).toSize(); + QSize value = QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok).toSize(); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::SizeF: { bool ok = false; - QSizeF value = QQmlStringConverters::sizeFFromString(binding->valueAsString(qmlUnit), &ok); + QSizeF value = QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Rect: { bool ok = false; - QRect value = QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok).toRect(); + QRect value = QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok).toRect(); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::RectF: { bool ok = false; - QRectF value = QQmlStringConverters::rectFFromString(binding->valueAsString(qmlUnit), &ok); + QRectF value = QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok); Q_ASSERT(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } @@ -570,7 +570,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float xp; float yp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector2D, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector2D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -582,7 +582,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float yp; float zy; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -595,7 +595,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float zy; float wp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -608,7 +608,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float yp; float zp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QQuaternion, binding->valueAsString(qmlUnit), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QQuaternion, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); Q_ASSERT(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -622,12 +622,12 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const if (property->propType() == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); QList value; - value.append(binding->valueAsNumber()); + value.append(binding->valueAsNumber(compilationUnit->constants)); property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType() == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number); - double n = binding->valueAsNumber(); + double n = binding->valueAsNumber(compilationUnit->constants); QList value; value.append(int(n)); property->writeProperty(_qobject, &value, propertyWriteFlags); @@ -640,7 +640,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; } else if (property->propType() == qMetaTypeId >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); - QString urlString = binding->valueAsString(qmlUnit); + QString urlString = binding->valueAsString(compilationUnit.data()); QUrl u = urlString.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(urlString)); QList value; @@ -650,7 +650,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else if (property->propType() == qMetaTypeId >()) { Q_ASSERT(binding->evaluatesToString()); QList value; - value.append(binding->valueAsString(qmlUnit)); + value.append(binding->valueAsString(compilationUnit.data())); property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType() == qMetaTypeId()) { @@ -658,20 +658,20 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { value = QJSValue(binding->valueAsBoolean()); } else if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double n = binding->valueAsNumber(); + double n = binding->valueAsNumber(compilationUnit->constants); if (double(int(n)) == n) { value = QJSValue(int(n)); } else value = QJSValue(n); } else { - value = QJSValue(binding->valueAsString(qmlUnit)); + value = QJSValue(binding->valueAsString(compilationUnit.data())); } property->writeProperty(_qobject, &value, propertyWriteFlags); break; } // otherwise, try a custom type assignment - QString stringValue = binding->valueAsString(qmlUnit); + QString stringValue = binding->valueAsString(compilationUnit.data()); QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(property->propType()); Q_ASSERT(converter); QVariant value = (*converter)(stringValue); @@ -804,13 +804,13 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper // ### resolve this at compile time if (bindingProperty && bindingProperty->propType() == qMetaTypeId()) { - QQmlScriptString ss(binding->valueAsScriptString(qmlUnit), context->asQQmlContext(), _scopeObject); + QQmlScriptString ss(binding->valueAsScriptString(compilationUnit.data()), context->asQQmlContext(), _scopeObject); ss.d.data()->bindingId = binding->type == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid; ss.d.data()->lineNumber = binding->location.line; ss.d.data()->columnNumber = binding->location.column; ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String; ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number; - ss.d.data()->numberValue = binding->valueAsNumber(); + ss.d.data()->numberValue = binding->valueAsNumber(compilationUnit->constants); QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 503e5cb88c..e352aa9d6c 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -313,7 +313,7 @@ QString StringOrTranslation::toString(const QQmlListModel *owner) const } if (!owner) return QString(); - return d.asT2()->valueAsString(owner->m_compilationUnit->unitData()); + return d.asT2()->valueAsString(owner->m_compilationUnit.data()); } QString StringOrTranslation::asString() const @@ -2682,7 +2682,7 @@ bool QQmlListModelParser::verifyProperty(const QQmlRefPointertype == QV4::CompiledData::Binding::Type_Script) { - QString scriptStr = binding->valueAsScriptString(compilationUnit->unitData()); + QString scriptStr = binding->valueAsScriptString(compilationUnit.data()); if (!binding->isFunctionExpression() && !definesEmptyList(scriptStr)) { QByteArray script = scriptStr.toUtf8(); bool ok; @@ -2734,13 +2734,13 @@ bool QQmlListModelParser::applyProperty(const QQmlRefPointerisTranslationBinding()) { value = QVariant::fromValue(binding); } else if (binding->evaluatesToString()) { - value = binding->valueAsString(qmlUnit); + value = binding->valueAsString(compilationUnit.data()); } else if (binding->type == QV4::CompiledData::Binding::Type_Number) { - value = binding->valueAsNumber(); + value = binding->valueAsNumber(compilationUnit->constants); } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { value = binding->valueAsBoolean(); } else if (binding->type == QV4::CompiledData::Binding::Type_Script) { - QString scriptStr = binding->valueAsScriptString(qmlUnit); + QString scriptStr = binding->valueAsScriptString(compilationUnit.data()); if (definesEmptyList(scriptStr)) { const ListLayout::Role &role = model->getOrCreateListRole(elementName); ListModel *emptyModel = new ListModel(role.subLayout, nullptr); diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 4ce904ffcf..df02b9f0c3 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -314,7 +314,7 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, QQmlBinding::Identifier id = QQmlBinding::Invalid; if (!binding->isTranslationBinding()) { - expression = binding->valueAsString(qmlUnit); + expression = binding->valueAsString(compilationUnit.data()); id = binding->value.compiledScriptIndex; } expressions << ExpressionChange(propertyName, binding, id, expression, url, line, column); @@ -328,10 +328,10 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, case QV4::CompiledData::Binding::Type_TranslationById: Q_UNREACHABLE(); case QV4::CompiledData::Binding::Type_String: - var = binding->valueAsString(qmlUnit); + var = binding->valueAsString(compilationUnit.data()); break; case QV4::CompiledData::Binding::Type_Number: - var = binding->valueAsNumber(); + var = binding->valueAsNumber(compilationUnit->constants); break; case QV4::CompiledData::Binding::Type_Boolean: var = binding->valueAsBoolean(); diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index 917ac9e74e..fa50997ae7 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -303,7 +303,7 @@ void tst_qmldiskcache::regenerateAfterChange() const QV4::CompiledData::Object *obj = testUnit->objectAt(0); QCOMPARE(quint32(obj->nBindings), quint32(2)); QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Number)); - QCOMPARE(obj->bindingTable()->valueAsNumber(), double(42)); + QCOMPARE(obj->bindingTable()->valueAsNumber(reinterpret_cast(testUnit->constants())), double(42)); QCOMPARE(quint32(testUnit->functionTableSize), quint32(1)); diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 1773164e69..4e95288f2b 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -2205,18 +2205,19 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode() QV4::CompiledData::Unit *qmlUnit = reinterpret_cast(malloc(readOnlyQmlUnit->unitSize)); memcpy(qmlUnit, readOnlyQmlUnit, readOnlyQmlUnit->unitSize); qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData; - td->compilationUnit()->setUnitData(qmlUnit); + QQmlRefPointer compilationUnit = td->compilationUnit(); + compilationUnit->setUnitData(qmlUnit); const QV4::CompiledData::Object *rootObject = qmlUnit->objectAt(/*root object*/0); - QCOMPARE(qmlUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject")); + QCOMPARE(compilationUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject")); quint32 i; for (i = 0; i < rootObject->nBindings; ++i) { const QV4::CompiledData::Binding *binding = rootObject->bindingTable() + i; - if (qmlUnit->stringAt(binding->propertyNameIndex) != QString("scriptProperty")) + if (compilationUnit->stringAt(binding->propertyNameIndex) != QString("scriptProperty")) continue; - QCOMPARE(binding->valueAsScriptString(qmlUnit), QString("intProperty")); + QCOMPARE(binding->valueAsScriptString(compilationUnit.data()), QString("intProperty")); const_cast(binding)->stringIndex = 0; // empty string index - QVERIFY(binding->valueAsScriptString(qmlUnit).isEmpty()); + QVERIFY(binding->valueAsScriptString(compilationUnit.data()).isEmpty()); break; } QVERIFY(i < rootObject->nBindings); -- cgit v1.2.3