diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-11-02 14:28:02 +0000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-04 11:27:52 +0100 |
commit | f9261feb16d02e985982dd46783ea54c2cfce91b (patch) | |
tree | 205743bcd164628f882aa35580fd136384a28acb /src/declarative/qml/qdeclarativeexpression_p.h | |
parent | 0dd867535bebf6db673d4f03959e62e94ff35ba2 (diff) |
Skip the captured properties step in bindings
Objects and notifiers in the capturedProperties list were not guarded
which can lead to crashes if they're deleted prior to the binding
completing. Now the notifiers are connected to and guarded immediately
to prevent this.
Change-Id: I912e323c52bf6169fb5077e552d5d38d9aa7faec
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/declarative/qml/qdeclarativeexpression_p.h')
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression_p.h | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index 4e31efb806..65b07ca7e8 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -55,10 +55,10 @@ #include "qdeclarativeexpression.h" -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativeguard_p.h> - #include <private/qv8engine_p.h> +#include <private/qfieldlist_p.h> +#include <private/qdeclarativeguard_p.h> +#include <private/qdeclarativeengine_p.h> QT_BEGIN_NAMESPACE @@ -164,28 +164,28 @@ private: QObject *m_scopeObject; - class GuardList { - public: - inline GuardList(); - inline ~GuardList(); - void inline clear(); - - typedef QPODVector<QDeclarativeEnginePrivate::CapturedProperty> CapturedProperties; - void updateGuards(QDeclarativeJavaScriptExpression *, const CapturedProperties &properties); - - private: - struct Endpoint : public QDeclarativeNotifierEndpoint { - Endpoint() : expression(0) { callback = &endpointCallback; } - static void endpointCallback(QDeclarativeNotifierEndpoint *e) { - static_cast<Endpoint *>(e)->expression->expressionChanged(); - } - QDeclarativeJavaScriptExpression *expression; - }; - - Endpoint *endpoints; - int length; + typedef QDeclarativeJavaScriptExpressionGuard Guard; + + struct GuardCapture : public QDeclarativeEnginePrivate::PropertyCapture { + GuardCapture(QDeclarativeJavaScriptExpression *e) : expression(e), errorString(0) { + } + ~GuardCapture() { + Q_ASSERT(guards.isEmpty()); + Q_ASSERT(errorString == 0); + } + + virtual void captureProperty(QDeclarativeNotifier *); + virtual void captureProperty(QObject *, int, int); + + QDeclarativeJavaScriptExpression *expression; + QFieldList<Guard, &Guard::next> guards; + QStringList *errorString; }; - GuardList guardList; + + QFieldList<Guard, &Guard::next> activeGuards; + GuardCapture *guardCapture; + + void clearGuards(); }; class QDeclarativeExpression; @@ -302,36 +302,42 @@ QString QDeclarativeJavaScriptExpression::expressionIdentifier() return QString(); } -QDeclarativeJavaScriptExpression::GuardList::GuardList() -: endpoints(0), length(0) +QDeclarativeExpressionPrivate *QDeclarativeExpressionPrivate::get(QDeclarativeExpression *expr) { + return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr)); } -QDeclarativeJavaScriptExpression::GuardList::~GuardList() -{ - clear(); +QDeclarativeExpression *QDeclarativeExpressionPrivate::get(QDeclarativeExpressionPrivate *expr) +{ + return expr->q_func(); } -void QDeclarativeJavaScriptExpression::GuardList::clear() +QString QDeclarativeExpressionPrivate::expressionIdentifier() +{ + return QLatin1String("\"") + expression + QLatin1String("\""); +} + +QDeclarativeJavaScriptExpressionGuard::QDeclarativeJavaScriptExpressionGuard(QDeclarativeJavaScriptExpression *e) +: expression(e), next(0) { - delete [] endpoints; - endpoints = 0; - length = 0; + callback = &endpointCallback; } -QDeclarativeExpressionPrivate *QDeclarativeExpressionPrivate::get(QDeclarativeExpression *expr) +void QDeclarativeJavaScriptExpressionGuard::endpointCallback(QDeclarativeNotifierEndpoint *e) { - return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr)); + static_cast<QDeclarativeJavaScriptExpressionGuard *>(e)->expression->expressionChanged(); } -QDeclarativeExpression *QDeclarativeExpressionPrivate::get(QDeclarativeExpressionPrivate *expr) +QDeclarativeJavaScriptExpressionGuard * +QDeclarativeJavaScriptExpressionGuard::New(QDeclarativeJavaScriptExpression *e) { - return expr->q_func(); + Q_ASSERT(e); + return QDeclarativeEnginePrivate::get(e->context()->engine)->jsExpressionGuardPool.New(e); } -QString QDeclarativeExpressionPrivate::expressionIdentifier() +void QDeclarativeJavaScriptExpressionGuard::Delete() { - return QLatin1String("\"") + expression + QLatin1String("\""); + QRecyclePool<QDeclarativeJavaScriptExpressionGuard>::Delete(this); } QT_END_NAMESPACE |