diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-30 16:49:32 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-25 22:04:42 +0100 |
commit | cf5185d1872f75b82876dd4e4ecdc3d27240f942 (patch) | |
tree | 9c8bbf9597bfa38a4b56d4b6557797a7b2def501 /src/qml/compiler/qv4jsir_p.h | |
parent | 222e06bf4ed509e72c1533cbe1d4859ca96933f3 (diff) |
Improve type interference for QObject properties
Propagate QObject properties in member expressions across temporaries
as part of the type interference SSA pass. This replaces the earlier
attempt to resolving QObject properties in fieldMemberExpression()
in the codegen, but it was incomplete and now things like the following
are fully resolved:
var tmp = blah.somePropertyThatReturnsAQQuickItem; <-- QQuickItem property return type propagated into tmp
var width = tmp.width; <-- and picked up here again to resolve the index of width instead of by name
With this patch Temp gets a helper structure with a function pointer,
initialized to aid the resolution of properties in Qt meta objects. This
structure is propagated into the temps until it reaches the next member
expression that uses the temp. Similarly QObjectType is added as IR type, next
to VarType.
The resolution inside the SSA type interference pass also requires passing
through the QQmlEngine from the upper caller levels, in order to resolve the
property type to a potential QMetaObject property.
Change-Id: I14c98fa455db57603da46613ce49c174d0944291
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4jsir_p.h')
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 9a1bd87a1d..cb8e9d9195 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -73,6 +73,8 @@ QT_BEGIN_NAMESPACE class QTextStream; class QQmlType; class QQmlPropertyData; +class QQmlPropertyCache; +class QQmlEnginePrivate; namespace QV4 { struct ExecutionContext; @@ -181,7 +183,8 @@ enum Type { NumberType = SInt32Type | UInt32Type | DoubleType, StringType = 1 << 7, - VarType = 1 << 8 + QObjectType = 1 << 8, + VarType = 1 << 9 }; inline bool strictlyEqualTypes(Type t1, Type t2) @@ -218,6 +221,21 @@ struct StmtVisitor { virtual void visitPhi(Phi *) = 0; }; + +struct MemberExpressionResolver +{ + typedef Type (*ResolveFunction)(QQmlEnginePrivate *engine, MemberExpressionResolver *resolver, Member *member); + + MemberExpressionResolver() + : resolveMember(0), data(0) {} + + bool isValid() const { return !!resolveMember; } + void clear() { *this = MemberExpressionResolver(); } + + ResolveFunction resolveMember; + void *data; // Could be pointer to meta object, QQmlTypeNameCache, etc. - depends on resolveMember implementation +}; + struct Expr { Type type; @@ -363,6 +381,8 @@ struct Temp: Expr { unsigned scope : 28; // how many scopes outside the current one? unsigned kind : 3; unsigned isArgumentsOrEval : 1; + // Used when temp is used as base in member expression + MemberExpressionResolver memberResolver; void init(unsigned kind, unsigned index, unsigned scope) { @@ -536,7 +556,6 @@ struct Member: Expr { this->type = MemberByName; this->base = base; this->name = name; - this->memberIndex = -1; this->property = 0; } @@ -554,6 +573,7 @@ struct Member: Expr { this->type = MemberOfQObject; this->base = base; this->name = name; + this->memberIndex = -1; this->property = property; } @@ -937,6 +957,7 @@ public: Temp *newTemp = f->New<Temp>(); newTemp->init(t->kind, t->index, t->scope); newTemp->type = t->type; + newTemp->memberResolver = t->memberResolver; return newTemp; } |