aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlvme.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2012-05-30 10:16:13 +0100
committerQt by Nokia <qt-info@nokia.com>2012-08-29 06:38:54 +0200
commit04774bb14c81688f86a2b31b8624bde8ebf59062 (patch)
tree9d04d18712988caca2a3f193feb94cfaa35b47bb /src/qml/qml/qqmlvme.cpp
parentd65fb68de12b6d811f7b94ba3209847f73ca94cc (diff)
Evaluate bindings more intelligently during construction
Instead of just evaluating bindings in a fixed order, and possibly having to evaluate a single binding multiple times, prior to reading a property, we check if there are any bindings "pending" on it and evaluate them then. A pending binding is one that has been assigned to the property, but not yet evaluated. To minimize side effects we only do this for "safe" bindings. A safe binding is one that has no side effects, which we currently define as not calling functions or otherwise assigning values during its evaluation. This isn't an entirely foolproof way to ensure that the evaluation has no side effects, but it should be good enough. Change-Id: I98aa76a95719e5d182e8941738d64f8d409f404a Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlvme.cpp')
-rw-r--r--src/qml/qml/qqmlvme.cpp33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 65658243ea..1f12af3102 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -201,12 +201,12 @@ QObject *QQmlVME::execute(QList<QQmlError> *errors, const Interrupt &interrupt)
inline bool fastHasBinding(QObject *o, int index)
{
- QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(o)->declarativeData);
-
- index &= 0x0000FFFF; // To handle value types
+ if (QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(o)->declarativeData)) {
+ int coreIndex = index & 0x0000FFFF;
+ return ddata->hasBindingBit(coreIndex);
+ }
- return ddata && (ddata->bindingBitsSize > index) &&
- (ddata->bindingBits[index / 32] & (1 << (index % 32)));
+ return false;
}
static void removeBindingOnProperty(QObject *o, int index)
@@ -867,6 +867,13 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
CLEAN_PROPERTY(target, instr.property);
binding->addToObject();
+
+ if (instr.propType == 0) {
+ // All non-valuetype V4 bindings are safe bindings
+ QQmlData *data = QQmlData::get(target);
+ Q_ASSERT(data);
+ data->setPendingBindingBit(target, propertyIdx);
+ }
}
QML_END_INSTR(StoreV4Binding)
@@ -876,7 +883,9 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QObject *scope =
objects.at(objects.count() - 1 - instr.context);
- if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex))
+ int coreIndex = instr.property.coreIndex;
+
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
QML_NEXT_INSTR(StoreV8Binding);
QQmlAbstractBinding *binding = CTXT->v8bindings->configBinding(target, scope,
@@ -887,8 +896,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
if (instr.isAlias) {
QQmlAbstractBinding *old =
- QQmlPropertyPrivate::setBindingNoEnable(target,
- instr.property.coreIndex,
+ QQmlPropertyPrivate::setBindingNoEnable(target, coreIndex,
instr.property.getValueTypeCoreIndex(),
binding);
if (old) { old->destroy(); }
@@ -900,6 +908,12 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property));
binding->addToObject();
+
+ if (instr.isSafe && !instr.property.isValueTypeVirtual()) {
+ QQmlData *data = QQmlData::get(target);
+ Q_ASSERT(data);
+ data->setPendingBindingBit(target, coreIndex);
+ }
}
}
QML_END_INSTR(StoreV8Binding)
@@ -1289,6 +1303,9 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
if (b) {
b->m_mePtr = 0;
+ QQmlData *data = QQmlData::get(b->object());
+ Q_ASSERT(data);
+ data->clearPendingBindingBit(b->propertyIndex());
b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
QQmlPropertyPrivate::DontRemoveBinding);
}