diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-24 14:51:02 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-31 10:50:38 +0100 |
commit | 34c85bb56c92316a6ce1c79d25f9653fec14791c (patch) | |
tree | 6d3d43de33fa53a1353c52506e989ae126f1361b /src/qml/compiler/qv4jsir.cpp | |
parent | bb7d26ebb0c2e7a9f06a030be8bfcd00e346e06f (diff) |
Initial support for resolving meta-property access for the scope and context objects at QML compile time
This avoids having to do a string lookup for ids and in the import cache at
run-time, before we can do a string hash lookup in the property cache. Instead
we resolve final properties in the context and scope object at compile time and
look them up at run-time using their index instead. The dependencies to these
properties are also tracked separately and recorded in the compiled data.
This is merely the initial patch. There's a lot left to do, such as having
specialized getter and setters for specific property types. Setters are missing
altogether right now and will fall back to name lookup.
Change-Id: If3cb4e7c9454ef4850a615f0935b311c9395b165
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4jsir.cpp')
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 86a13cfe99..a3654a1bea 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -42,6 +42,7 @@ #include "qv4jsir_p.h" #include <private/qqmljsast_p.h> +#include <private/qqmlpropertycache_p.h> #include <QtCore/qtextstream.h> #include <QtCore/qdebug.h> #include <QtCore/qset.h> @@ -423,6 +424,10 @@ static const char *builtin_to_string(Name::Builtin b) return "builtin_setup_argument_object"; case V4IR::Name::builtin_qml_id_scope: return "builtin_qml_id_scope"; + case V4IR::Name::builtin_qml_scope_object: + return "builtin_qml_scope_object"; + case V4IR::Name::builtin_qml_context_object: + return "builtin_qml_context_object"; } return "builtin_(###FIXME)"; }; @@ -532,6 +537,8 @@ void Member::dump(QTextStream &out) const { base->dump(out); out << '.' << *name; + if (type == MemberOfQObject) + out << " (meta-property " << property->coreIndex << " <" << QMetaType::typeName(property->propType) << ">)"; } void Exp::dump(QTextStream &out, Mode) @@ -819,11 +826,18 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name) return e; } -Expr *BasicBlock::QML_CONTEXT_ID_MEMBER(const QString &id, int objectId, quint32 line, quint32 column) +Expr *BasicBlock::QML_CONTEXT_ID_MEMBER(Expr *base, const QString *id, int objectId) { Member*e = function->New<Member>(); - Name *base = NAME(Name::builtin_qml_id_scope, line, column); - e->initQmlIdObject(base, function->newString(id), objectId); + Q_ASSERT(base->asName() && base->asName()->builtin == Name::builtin_qml_id_scope); + e->initQmlIdObject(base, id, objectId); + return e; +} + +Expr *BasicBlock::QML_QOBJECT_PROPERTY(Expr *base, const QString *id, QQmlPropertyData *property) +{ + Member*e = function->New<Member>(); + e->initMetaProperty(base, id, property); return e; } @@ -1013,12 +1027,30 @@ void CloneExpr::visitSubscript(Subscript *e) void CloneExpr::visitMember(Member *e) { - Member *m = static_cast<Member*>(block->MEMBER(clone(e->base), e->name)); - if (e->type == Member::MemberByObjectId) { - m->type = e->type; - m->objectId = e->objectId; + if (e->type == Member::MemberByName) + cloned = block->MEMBER(clone(e->base), e->name); + else if (e->type == Member::MemberByObjectId) + cloned = block->QML_CONTEXT_ID_MEMBER(clone(e->base), e->name, e->objectId); + else if (e->type == Member::MemberOfQObject) + cloned = block->QML_QOBJECT_PROPERTY(clone(e->base), e->name, e->property); + else + Q_ASSERT(!"Unimplemented!"); +} + +void QmlDependenciesCollector::visitMember(Member *e) { + e->base->accept(this); + if (e->type == Member::MemberByObjectId) + _usedIdObjects.insert(e->objectId); + else if (e->type == Member::MemberOfQObject + && !e->property->isFunction()) { // only non-functions have notifyIndex + + if (Name *base = e->base->asName()) { + if (base->builtin == Name::builtin_qml_context_object) + _usedContextProperties.insert(e->property); + else if (base->builtin == Name::builtin_qml_scope_object) + _usedScopeProperties.insert(e->property); + } } - cloned = m; } void QmlDependenciesCollector::visitPhi(Phi *s) { |