diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-25 15:03:01 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-31 16:01:03 +0100 |
commit | b566c9121c066669a88f01143034078ae0cccc90 (patch) | |
tree | c8d080fba288cb0efdd025f99195e3c5b23316db /src/qml/compiler/qv4ssa.cpp | |
parent | 71338b4b2f01268759f7ac6b3eff5abb17420a7c (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.cpp | 37 |
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) { |