aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4ssa.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-25 15:03:01 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-31 16:01:03 +0100
commitb566c9121c066669a88f01143034078ae0cccc90 (patch)
treec8d080fba288cb0efdd025f99195e3c5b23316db /src/qml/compiler/qv4ssa.cpp
parent71338b4b2f01268759f7ac6b3eff5abb17420a7c (diff)
Propagate bool/int/double/string types from QML into the IR
... by mapping the property type to the IR type if possible. In an expression like parent.width * 0.5 this avoids a to-double conversion for parent.width but instead we can rely on the result of the property read for the width property to always be a double. Unfortunately integer propertyes are currently not propagated, because upon assignment from a double we would do the ECMAScript compliant truncation while QML actually expects a round to happen. This needs to be solved separately. Change-Id: I9c8f58416201d406e6e11d157cae12a686b774e5 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4ssa.cpp')
-rw-r--r--src/qml/compiler/qv4ssa.cpp37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 77ee957538..1c88740ef1 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -51,6 +51,7 @@
#include <QtCore/QStack>
#include <qv4runtime_p.h>
#include <qv4context_p.h>
+#include <private/qqmlpropertycache_p.h>
#include <cmath>
#include <iostream>
#include <cassert>
@@ -1499,7 +1500,12 @@ protected:
}
virtual void visitMember(Member *e) {
- // TODO: for QML, try to do a static lookup
+ if (e->type == Member::MemberOfQObject
+ && !e->property->isEnum() // Enums need to go through run-time getters/setters to ensure correct string handling.
+ ) {
+ _ty = TypingResult(irTypeFromPropertyType(e->property->propType));
+ return;
+ }
_ty = run(e->base);
_ty.type = VarType;
}
@@ -1561,6 +1567,21 @@ protected:
setType(s->targetTemp, _ty.type);
}
+
+ static int irTypeFromPropertyType(int propType)
+ {
+ switch (propType) {
+ case QMetaType::Bool: return BoolType;
+
+ // Can't propagate integers right now, because QML rounds doubles to integers on assignment, as opposed to EcmaScript
+// case QMetaType::Int: return SInt32Type;
+
+ case QMetaType::Double: return DoubleType;
+ case QMetaType::QString: return StringType;
+ default: break;
+ }
+ return VarType;
+ }
};
void convertConst(Const *c, Type targetType)
@@ -1650,7 +1671,11 @@ public:
}
foreach (const Conversion &conversion, _conversions) {
- if (conversion.stmt->asMove() && conversion.stmt->asMove()->source->asTemp()) {
+ V4IR::Move *move = conversion.stmt->asMove();
+
+ // Note: isel only supports move into member when source is a temp, so convert
+ // is not a supported source.
+ if (move && move->source->asTemp() && !move->target->asMember()) {
*conversion.expr = bb->CONVERT(*conversion.expr, conversion.targetType);
} else if (Const *c = (*conversion.expr)->asConst()) {
convertConst(c, conversion.targetType);
@@ -1788,7 +1813,13 @@ protected:
}
}
- run(s->source, s->target->type);
+ // Resettable properties need to be able to receive the un-converted
+ // value, because assigning "undefined" to them calls the reset function
+ // of the property.
+ const Member *targetMember = s->target->asMember();
+ const bool inhibitConversion = targetMember && targetMember->type == Member::MemberOfQObject && targetMember->property->isResettable();
+
+ run(s->source, s->target->type, !inhibitConversion);
}
virtual void visitJump(Jump *) {}
virtual void visitCJump(CJump *s) {