diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-12-04 16:30:54 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-05 22:05:21 +0100 |
commit | 7a344ef2b7796731a69a4f36e13ca9cf6f3b1ee9 (patch) | |
tree | 2de37c20020a321d1206208eccd78c8a89c08388 /src/qml | |
parent | 41aca0cebf3b49597ad0614e3789bbeff5191ff4 (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.cpp | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 4 |
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; |