aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-12-04 16:30:54 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-05 22:05:21 +0100
commit7a344ef2b7796731a69a4f36e13ca9cf6f3b1ee9 (patch)
tree2de37c20020a321d1206208eccd78c8a89c08388 /src/qml
parent41aca0cebf3b49597ad0614e3789bbeff5191ff4 (diff)
Fix dependency calculation for context and scope properties
We were incorrectly calculating writing to a context or scope property as a dependency for an expression. We don't know whether a property is being written only or also being read from at lookup time, but we can make that decision in the isel then when generating the move instructions. So initially context and scope properties end up in a candidate set first and get promoted to real dependencies when they're being used in reading moves. Task-number: QTBUG-35210 Change-Id: Ia67057abafc2d611e1e6605327b4965ebe91cbed Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp4
-rw-r--r--src/qml/compiler/qv4isel_p.cpp13
-rw-r--r--src/qml/compiler/qv4jsir_p.h4
3 files changed, 17 insertions, 4 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 7ebe4dcba2..8693c32c92 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1595,7 +1595,7 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
return 0;
if (pd) {
if (!pd->isConstant())
- _function->scopeObjectDependencies.insert(pd);
+ _function->scopeObjectDependencyCandidates.insert(pd); // We don't know if we'll ever read from there or just write, hence candidate
V4IR::Temp *base = _block->TEMP(_scopeObjectTemp);
initMetaObjectResolver(&base->memberResolver, _scopeObject);
return _block->MEMBER(base, _function->newString(name), pd);
@@ -1609,7 +1609,7 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
return 0;
if (pd) {
if (!pd->isConstant())
- _function->contextObjectDependencies.insert(pd);
+ _function->contextObjectDependencyCandidates.insert(pd); // We don't know if we'll ever read from there or just write, hence candidate
V4IR::Temp *base = _block->TEMP(_contextObjectTemp);
initMetaObjectResolver(&base->memberResolver, _contextObject);
return _block->MEMBER(base, _function->newString(name), pd);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 7ba43dd552..78eb9ba0f5 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -149,8 +149,17 @@ void IRDecoder::visitMove(V4IR::Move *s)
if (m->property) {
bool captureRequired = true;
if (_function && m->attachedPropertiesId == 0) {
- captureRequired = !_function->contextObjectDependencies.contains(m->property)
- && !_function->scopeObjectDependencies.contains(m->property);
+ if (_function->contextObjectDependencyCandidates.remove(m->property)) {
+ _function->contextObjectDependencies.insert(m->property);
+ captureRequired = false;
+ } else if (_function->scopeObjectDependencyCandidates.remove(m->property)) {
+ _function->scopeObjectDependencies.insert(m->property);
+ captureRequired = false;
+ }
+
+ if (captureRequired)
+ captureRequired = !_function->contextObjectDependencies.contains(m->property)
+ && !_function->scopeObjectDependencies.contains(m->property);
}
getQObjectProperty(m->base, m->property->coreIndex, captureRequired, m->attachedPropertiesId, t);
return;
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 59e8d02bbc..b0ca4c0478 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -782,6 +782,10 @@ struct Function {
// Qml extension:
QSet<int> idObjectDependencies;
+ // Context/Scope properties discovered during identifier resolution
+ QSet<QQmlPropertyData*> contextObjectDependencyCandidates;
+ QSet<QQmlPropertyData*> scopeObjectDependencyCandidates;
+ // Context/Scope properties actually being read from, not only written
QSet<QQmlPropertyData*> contextObjectDependencies;
QSet<QQmlPropertyData*> scopeObjectDependencies;