summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-07-20 15:19:17 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-07-31 07:28:28 +0000
commitfcf9b7efa5b2a0d8f49e59b2a977b8122632aff6 (patch)
tree18f37a5a7775c5876947236fc6913a3a3e227f36
parent8e45393d10ca649c46a82eb8c125bd38cc5b5615 (diff)
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 <lars.knoll@qt.io>
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp4
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp36
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp8
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h1
-rw-r--r--src/qml/compiler/qv4compileddata.cpp10
-rw-r--r--src/qml/compiler/qv4compileddata_p.h21
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp68
-rw-r--r--src/qml/types/qqmllistmodel.cpp10
-rw-r--r--src/quick/util/qquickpropertychanges.cpp6
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp11
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<QQmlJS::AST::NumericLiteral *>(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<QQmlJS::AST::CallExpression *>(expr)) {
if (QQmlJS::AST::IdentifierExpression *base = QQmlJS::AST::cast<QQmlJS::AST::IdentifierExpression *>(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<QQmlJS::AST::UnaryMinusExpression *>(expr)) {
if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(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<QList<int> >()) {
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<quint64>(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<quint64>(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<QList<qreal> >()) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
QList<qreal> value;
- value.append(binding->valueAsNumber());
+ value.append(binding->valueAsNumber(compilationUnit->constants));
property->writeProperty(_qobject, &value, propertyWriteFlags);
break;
} else if (property->propType() == qMetaTypeId<QList<int> >()) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
- double n = binding->valueAsNumber();
+ double n = binding->valueAsNumber(compilationUnit->constants);
QList<int> 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<QList<QUrl> >()) {
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<QUrl> value;
@@ -650,7 +650,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
} else if (property->propType() == qMetaTypeId<QList<QString> >()) {
Q_ASSERT(binding->evaluatesToString());
QList<QString> value;
- value.append(binding->valueAsString(qmlUnit));
+ value.append(binding->valueAsString(compilationUnit.data()));
property->writeProperty(_qobject, &value, propertyWriteFlags);
break;
} else if (property->propType() == qMetaTypeId<QJSValue>()) {
@@ -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>()) {
- 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 QQmlRefPointer<QV4::CompiledData:
return false;
}
} else if (binding->type == 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 QQmlRefPointer<QV4::CompiledData::
if (binding->isTranslationBinding()) {
value = QVariant::fromValue<const QV4::CompiledData::Binding*>(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<const QV4::Value *>(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<QV4::CompiledData::Unit *>(malloc(readOnlyQmlUnit->unitSize));
memcpy(qmlUnit, readOnlyQmlUnit, readOnlyQmlUnit->unitSize);
qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
- td->compilationUnit()->setUnitData(qmlUnit);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> 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<QV4::CompiledData::Binding*>(binding)->stringIndex = 0; // empty string index
- QVERIFY(binding->valueAsScriptString(qmlUnit).isEmpty());
+ QVERIFY(binding->valueAsScriptString(compilationUnit.data()).isEmpty());
break;
}
QVERIFY(i < rootObject->nBindings);