summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-01-27 03:32:24 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-01-27 05:18:17 (GMT)
commit01a946c6b3838a1c094687785be041b156ac1410 (patch)
treeb22473b4a696d74249884e3ae5351afde57e4969
parent6f1d4e8bdd9a11a4d35c8386e0c7e236bcfebd95 (diff)
downloadQt-01a946c6b3838a1c094687785be041b156ac1410.zip
Qt-01a946c6b3838a1c094687785be041b156ac1410.tar.gz
Qt-01a946c6b3838a1c094687785be041b156ac1410.tar.bz2
Cleanup
-rw-r--r--src/declarative/qml/qml.pri6
-rw-r--r--src/declarative/qml/qmlbindingoptimizations.cpp173
-rw-r--r--src/declarative/qml/qmlbindingvme_p.h182
-rw-r--r--src/declarative/qml/qmlcompiledbindings.cpp (renamed from src/declarative/qml/qmlbindingvme.cpp)400
-rw-r--r--src/declarative/qml/qmlcompiledbindings_p.h (renamed from src/declarative/qml/qmlbindingoptimizations_p.h)69
-rw-r--r--src/declarative/qml/qmlcompiler.cpp4
-rw-r--r--src/declarative/qml/qmlcontext.cpp4
-rw-r--r--src/declarative/qml/qmlcontext_p.h62
-rw-r--r--src/declarative/qml/qmlvme.cpp4
9 files changed, 415 insertions, 489 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 9268545..6f2f57f 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -32,9 +32,8 @@ SOURCES += \
$$PWD/qmlscriptparser.cpp \
$$PWD/qmlenginedebug.cpp \
$$PWD/qmlrewrite.cpp \
- $$PWD/qmlbindingvme.cpp \
$$PWD/qmlvaluetype.cpp \
- $$PWD/qmlbindingoptimizations.cpp \
+ $$PWD/qmlcompiledbindings.cpp \
$$PWD/qmlxmlhttprequest.cpp \
$$PWD/qmlsqldatabase.cpp \
$$PWD/qmetaobjectbuilder.cpp \
@@ -95,13 +94,12 @@ HEADERS += \
$$PWD/qmldeclarativedata_p.h \
$$PWD/qmlerror.h \
$$PWD/qmlscriptparser_p.h \
- $$PWD/qmlbindingvme_p.h \
$$PWD/qmlenginedebug_p.h \
$$PWD/qmlrewrite_p.h \
$$PWD/qpodvector_p.h \
$$PWD/qbitfield_p.h \
$$PWD/qmlvaluetype_p.h \
- $$PWD/qmlbindingoptimizations_p.h \
+ $$PWD/qmlcompiledbindings_p.h \
$$PWD/qmlxmlhttprequest_p.h \
$$PWD/qmlsqldatabase_p.h \
$$PWD/qmetaobjectbuilder_p.h \
diff --git a/src/declarative/qml/qmlbindingoptimizations.cpp b/src/declarative/qml/qmlbindingoptimizations.cpp
deleted file mode 100644
index 1e49636..0000000
--- a/src/declarative/qml/qmlbindingoptimizations.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlbindingoptimizations_p.h"
-
-#include "qmlcontext_p.h"
-#include <QtDeclarative/qmlinfo.h>
-#include "qmlbindingvme_p.h"
-
-QT_BEGIN_NAMESPACE
-
-int QmlOptimizedBindings::methodCount = -1;
-
-QmlOptimizedBindings::QmlOptimizedBindings(const char *program, QmlContext *context)
-: m_program(program)
-{
- if (methodCount == -1)
- methodCount = QmlOptimizedBindings::staticMetaObject.methodCount();
-
- m_config.target = this;
- m_config.targetSlot = metaObject()->methodCount();
-
- quint32 bindings = 0;
- QmlBindingVME::init(m_program, &m_config, &m_signalTable, &bindings);
-
- m_bindings = new Binding[bindings];
-
- QmlAbstractExpression::setContext(context);
-}
-
-QmlOptimizedBindings::~QmlOptimizedBindings()
-{
- delete [] m_bindings;
-}
-
-QmlAbstractBinding *QmlOptimizedBindings::configBinding(int index, QObject *target,
- QObject *scope, int property)
-{
- Binding *rv = m_bindings + index;
-
- rv->index = index;
- rv->property = property;
- rv->target = target;
- rv->scope = scope;
- rv->parent = this;
-
- addref(); // This is decremented in Binding::destroy()
-
- return rv;
-}
-
-void QmlOptimizedBindings::Binding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags)
-{
- if (e) {
- addToObject(target);
- update(flags);
- } else {
- removeFromObject();
- }
-
- QmlAbstractBinding::setEnabled(e, flags);
-
- if (enabled != e) {
- enabled = e;
-
- if (e) update(flags);
- }
-}
-
-int QmlOptimizedBindings::Binding::propertyIndex()
-{
- return property & 0xFFFF;
-}
-
-void QmlOptimizedBindings::Binding::update(QmlMetaProperty::WriteFlags)
-{
- parent->run(this);
-}
-
-void QmlOptimizedBindings::Binding::destroy()
-{
- enabled = false;
- removeFromObject();
- parent->release();
-}
-
-int QmlOptimizedBindings::qt_metacall(QMetaObject::Call c, int id, void **)
-{
- if (c == QMetaObject::InvokeMetaMethod && id >= methodCount) {
- id -= methodCount;
-
- quint32 *reeval = m_signalTable + m_signalTable[id];
- quint32 count = *reeval;
- ++reeval;
- for (quint32 ii = 0; ii < count; ++ii) {
- run(m_bindings + reeval[ii]);
- }
- }
- return -1;
-}
-
-void QmlOptimizedBindings::run(Binding *binding)
-{
- if (!binding->enabled)
- return;
- if (binding->updating)
- qWarning("ERROR: Circular binding");
-
- QmlContext *context = QmlAbstractExpression::context();
- if (!context) {
- qWarning("QmlOptimizedBindings: Attempted to evaluate an expression in an invalid context");
- return;
- }
- QmlContextPrivate *cp = QmlContextPrivate::get(context);
-
- if (binding->property & 0xFFFF0000) {
- QmlEnginePrivate *ep = QmlEnginePrivate::get(cp->engine);
-
- QmlValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
- Q_ASSERT(vt);
- vt->read(binding->target, binding->property & 0xFFFF);
-
- QObject *target = vt;
- QmlBindingVME::run(m_program, binding->index, &m_config, cp, binding,
- binding->scope, target);
-
- vt->write(binding->target, binding->property & 0xFFFF,
- QmlMetaProperty::DontRemoveBinding);
- } else {
- QmlBindingVME::run(m_program, binding->index, &m_config, cp, binding,
- binding->scope, binding->target);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlbindingvme_p.h b/src/declarative/qml/qmlbindingvme_p.h
deleted file mode 100644
index 01280f0..0000000
--- a/src/declarative/qml/qmlbindingvme_p.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMLBINDINGVME_P_H
-#define QMLBINDINGVME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <private/qscriptdeclarativeclass_p.h>
-#include "qmlexpression_p.h"
-#include "qmlguard_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QmlContextPrivate;
-class QmlBindingVME
-{
-public:
- struct Config {
- Config() : target(0), targetSlot(-1), subscriptions(0), identifiers(0) {}
- ~Config() { delete [] subscriptions; delete [] identifiers; }
- QObject *target;
- int targetSlot;
-
- struct Subscription {
- struct Signal {
- QmlGuard<QObject> source;
- int notifyIndex;
- };
-
- struct Id {
- inline Id();
- inline ~Id();
- inline void reset();
- Id *next;
- Id**prev;
- QObject *target;
- int methodIndex;
- };
-
- enum { InvalidType, SignalType, IdType } type;
- inline Subscription();
- inline ~Subscription();
- bool isSignal() const { return type == SignalType; }
- bool isId() const { return type == IdType; }
- inline Signal *signal();
- inline Id *id();
- union {
- char signalData[sizeof(Signal)];
- char idData[sizeof(Id)];
- };
- };
- Subscription *subscriptions;
- QScriptDeclarativeClass::PersistentIdentifier *identifiers;
- };
-
- static void init(const char *program, Config *config,
- quint32 **sigTable, quint32 *bindingCount);
- static void run(const char *program, int instr,
- Config *config, QmlContextPrivate *context, QmlDelayedError *error,
- QObject *scope, QObject *output);
- static void dump(const char *);
-};
-
-QmlBindingVME::Config::Subscription::Subscription()
-: type(InvalidType)
-{
-}
-
-QmlBindingVME::Config::Subscription::~Subscription()
-{
- if (type == SignalType) ((Signal *)signalData)->~Signal();
- else if (type == IdType) ((Id *)idData)->~Id();
-}
-
-QmlBindingVME::Config::Subscription::Id::Id()
-: next(0), prev(0), target(0), methodIndex(-1)
-{
-}
-
-QmlBindingVME::Config::Subscription::Id::~Id()
-{
- reset();
-}
-
-void QmlBindingVME::Config::Subscription::Id::reset()
-{
- if (next) next->prev = prev;
- if (prev) *prev = next;
- next = 0;
- prev = 0;
- target = 0;
- methodIndex = -1;
-}
-
-class QmlBindingCompilerPrivate;
-class QmlBindingCompiler
-{
-public:
- QmlBindingCompiler();
- ~QmlBindingCompiler();
-
- // Returns true if bindings were compiled
- bool isValid() const;
-
- struct Expression
- {
- QmlParser::Object *component;
- QmlParser::Object *context;
- QmlParser::Property *property;
- QmlParser::Variant expression;
- QHash<QString, QmlParser::Object *> ids;
- QmlEnginePrivate::Imports imports;
- };
-
- // -1 on failure, otherwise the binding index to use
- int compile(const Expression &, QmlEnginePrivate *);
-
- // Returns the compiled program
- QByteArray program() const;
-
-private:
- QmlBindingCompilerPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMLBINDINGVME_P_H
-
diff --git a/src/declarative/qml/qmlbindingvme.cpp b/src/declarative/qml/qmlcompiledbindings.cpp
index 47f02b2..d09f7eb 100644
--- a/src/declarative/qml/qmlbindingvme.cpp
+++ b/src/declarative/qml/qmlcompiledbindings.cpp
@@ -39,7 +39,9 @@
**
****************************************************************************/
-#include "qmlbindingvme_p.h"
+#include "qmlcompiledbindings_p.h"
+
+#include <QtDeclarative/qmlinfo.h>
#include <private/qmlcontext_p.h>
#include <private/qmljsast_p.h>
#include <private/qmljsengine_p.h>
@@ -52,22 +54,6 @@ QT_BEGIN_NAMESPACE
using namespace QmlJS;
-QmlBindingVME::Config::Subscription::Signal *QmlBindingVME::Config::Subscription::signal()
-{
- if (type == IdType) ((Id *)idData)->~Id();
- if (type != SignalType) new (signalData) Signal;
- type = SignalType;
- return (Signal *)signalData;
-}
-
-QmlBindingVME::Config::Subscription::Id *QmlBindingVME::Config::Subscription::id()
-{
- if (type == SignalType) ((Signal *)signalData)->~Signal();
- if (type != IdType) new (idData) Id;
- type = IdType;
- return (Id *)idData;
-}
-
namespace {
// Supported types: int, qreal, QString (needs constr/destr), QObject*, bool
struct Register {
@@ -106,7 +92,258 @@ struct Register {
int type; // Optional type
void *data[2]; // Object stored here
};
+}
+
+class QmlCompiledBindingsPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlCompiledBindings)
+
+public:
+ QmlCompiledBindingsPrivate();
+ virtual ~QmlCompiledBindingsPrivate();
+
+ struct Binding : public QmlAbstractBinding, public QmlDelayedError {
+ Binding() : enabled(false), updating(0), property(0),
+ scope(0), target(0), parent(0) {}
+
+ // Inherited from QmlAbstractBinding
+ virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags);
+ virtual int propertyIndex();
+ virtual void update(QmlMetaProperty::WriteFlags flags);
+ virtual void destroy();
+
+ int index:30;
+ bool enabled:1;
+ bool updating:1;
+ int property;
+ QObject *scope;
+ QObject *target;
+
+ QmlCompiledBindingsPrivate *parent;
+ };
+
+ struct Subscription {
+ struct Signal {
+ QmlGuard<QObject> source;
+ int notifyIndex;
+ };
+
+ enum { InvalidType, SignalType, IdType } type;
+ inline Subscription();
+ inline ~Subscription();
+ bool isSignal() const { return type == SignalType; }
+ bool isId() const { return type == IdType; }
+ inline Signal *signal();
+ inline QmlContextPrivate::IdNotifier *id();
+ union {
+ char signalData[sizeof(Signal)];
+ char idData[sizeof(QmlContextPrivate::IdNotifier)];
+ };
+ };
+ Subscription *subscriptions;
+ QScriptDeclarativeClass::PersistentIdentifier *identifiers;
+
+ void run(Binding *);
+
+ const char *programData;
+ Binding *m_bindings;
+ quint32 *m_signalTable;
+
+ static int methodCount;
+
+ void init();
+ void run(int instr, QmlContextPrivate *context,
+ QmlDelayedError *error, QObject *scope, QObject *output);
+
+
+ inline void unsubscribe(int subIndex);
+ inline void subscribeId(QmlContextPrivate *p, int idIndex, int subIndex);
+ inline void subscribe(QObject *o, int notifyIndex, int subIndex);
+
+ QmlPropertyCache::Data *findproperty(QObject *obj,
+ const QScriptDeclarativeClass::Identifier &name,
+ QmlEnginePrivate *enginePriv,
+ QmlPropertyCache::Data &local);
+ bool findproperty(QObject *obj,
+ Register *output,
+ QmlEnginePrivate *enginePriv,
+ int subIdx,
+ const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal);
+ void findgeneric(Register *output, // value output
+ int subIdx, // Subscription index in config
+ QmlContextPrivate *context, // Context to search in
+ const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal);
+};
+
+QmlCompiledBindingsPrivate::QmlCompiledBindingsPrivate()
+: subscriptions(0), identifiers(0)
+{
+}
+
+QmlCompiledBindingsPrivate::~QmlCompiledBindingsPrivate()
+{
+ delete [] subscriptions; subscriptions = 0;
+ delete [] identifiers; identifiers = 0;
+}
+
+QmlCompiledBindingsPrivate::Subscription::Subscription()
+: type(InvalidType)
+{
+}
+
+QmlCompiledBindingsPrivate::Subscription::~Subscription()
+{
+ if (type == SignalType) ((Signal *)signalData)->~Signal();
+ else if (type == IdType) ((QmlContextPrivate::IdNotifier *)idData)->~IdNotifier();
+}
+
+
+int QmlCompiledBindingsPrivate::methodCount = -1;
+
+QmlCompiledBindings::QmlCompiledBindings(const char *program, QmlContext *context)
+: QObject(*(new QmlCompiledBindingsPrivate))
+{
+ Q_D(QmlCompiledBindings);
+
+ if (d->methodCount == -1)
+ d->methodCount = QmlCompiledBindings::staticMetaObject.methodCount();
+
+ d->programData = program;
+
+ d->init();
+
+ QmlAbstractExpression::setContext(context);
+}
+
+QmlCompiledBindings::~QmlCompiledBindings()
+{
+ Q_D(QmlCompiledBindings);
+
+ delete [] d->m_bindings;
+}
+
+QmlAbstractBinding *QmlCompiledBindings::configBinding(int index, QObject *target,
+ QObject *scope, int property)
+{
+ Q_D(QmlCompiledBindings);
+
+ QmlCompiledBindingsPrivate::Binding *rv = d->m_bindings + index;
+
+ rv->index = index;
+ rv->property = property;
+ rv->target = target;
+ rv->scope = scope;
+ rv->parent = d;
+
+ addref(); // This is decremented in Binding::destroy()
+
+ return rv;
+}
+
+void QmlCompiledBindingsPrivate::Binding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags)
+{
+ if (e) {
+ addToObject(target);
+ update(flags);
+ } else {
+ removeFromObject();
+ }
+ QmlAbstractBinding::setEnabled(e, flags);
+
+ if (enabled != e) {
+ enabled = e;
+
+ if (e) update(flags);
+ }
+}
+
+int QmlCompiledBindingsPrivate::Binding::propertyIndex()
+{
+ return property & 0xFFFF;
+}
+
+void QmlCompiledBindingsPrivate::Binding::update(QmlMetaProperty::WriteFlags)
+{
+ parent->run(this);
+}
+
+void QmlCompiledBindingsPrivate::Binding::destroy()
+{
+ enabled = false;
+ removeFromObject();
+ parent->q_func()->release();
+}
+
+int QmlCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void **)
+{
+ Q_D(QmlCompiledBindings);
+
+ if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) {
+ id -= d->methodCount;
+
+ quint32 *reeval = d->m_signalTable + d->m_signalTable[id];
+ quint32 count = *reeval;
+ ++reeval;
+ for (quint32 ii = 0; ii < count; ++ii) {
+ d->run(d->m_bindings + reeval[ii]);
+ }
+ }
+ return -1;
+}
+
+void QmlCompiledBindingsPrivate::run(Binding *binding)
+{
+ Q_Q(QmlCompiledBindings);
+
+ if (!binding->enabled)
+ return;
+ if (binding->updating)
+ qWarning("ERROR: Circular binding");
+
+ QmlContext *context = q->QmlAbstractExpression::context();
+ if (!context) {
+ qWarning("QmlCompiledBindings: Attempted to evaluate an expression in an invalid context");
+ return;
+ }
+ QmlContextPrivate *cp = QmlContextPrivate::get(context);
+
+ if (binding->property & 0xFFFF0000) {
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(cp->engine);
+
+ QmlValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
+ Q_ASSERT(vt);
+ vt->read(binding->target, binding->property & 0xFFFF);
+
+ QObject *target = vt;
+ run(binding->index, cp, binding, binding->scope, target);
+
+ vt->write(binding->target, binding->property & 0xFFFF,
+ QmlMetaProperty::DontRemoveBinding);
+ } else {
+ run(binding->index, cp, binding, binding->scope, binding->target);
+ }
+}
+
+QmlCompiledBindingsPrivate::Subscription::Signal *QmlCompiledBindingsPrivate::Subscription::signal()
+{
+ if (type == IdType) ((QmlContextPrivate::IdNotifier *)idData)->~IdNotifier();
+ if (type != SignalType) new (signalData) Signal;
+ type = SignalType;
+ return (Signal *)signalData;
+}
+
+QmlContextPrivate::IdNotifier *QmlCompiledBindingsPrivate::Subscription::id()
+{
+ if (type == SignalType) ((Signal *)signalData)->~Signal();
+ if (type != IdType) new (idData) QmlContextPrivate::IdNotifier;
+ type = IdType;
+ return (QmlContextPrivate::IdNotifier *)idData;
+}
+
+namespace {
// This structure is exactly 8-bytes in size
struct Instr {
enum {
@@ -411,68 +648,72 @@ struct QmlBindingCompilerPrivate
QByteArray buildExceptionData() const;
};
-inline void unsubscribe(int subIndex, QmlBindingVME::Config *config)
+void QmlCompiledBindingsPrivate::unsubscribe(int subIndex)
{
- QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex);
+ Q_Q(QmlCompiledBindings);
+
+ QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
if (sub->isSignal()) {
- QmlBindingVME::Config::Subscription::Signal *s = sub->signal();
+ QmlCompiledBindingsPrivate::Subscription::Signal *s = sub->signal();
if (s->source)
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
QMetaObject::disconnectOne(s->source, s->notifyIndex,
- config->target, config->targetSlot + subIndex);
+ q, methodCount + subIndex);
#else
// QTBUG-6781
QMetaObject::disconnect(s->source, s->notifyIndex,
- config->target, config->targetSlot + subIndex);
+ q, methodCount + subIndex);
#endif
} else if (sub->isId()) {
- sub->id()->reset();
+ sub->id()->clear();
}
}
-inline void subscribeId(QmlContextPrivate *p, int idIndex,
- int subIndex, QmlBindingVME::Config *config)
+void QmlCompiledBindingsPrivate::subscribeId(QmlContextPrivate *p, int idIndex, int subIndex)
{
- unsubscribe(subIndex, config);
+ Q_Q(QmlCompiledBindings);
+
+ unsubscribe(subIndex);
if (p->idValues[idIndex]) {
- QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex);
- QmlBindingVME::Config::Subscription::Id *i = sub->id();
+ QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ QmlContextPrivate::IdNotifier *i = sub->id();
i->next = p->idValues[idIndex].bindings;
i->prev = &p->idValues[idIndex].bindings;
p->idValues[idIndex].bindings = i;
if (i->next) i->next->prev = &i->next;
- i->target = config->target;
- i->methodIndex = config->targetSlot + subIndex;
+ i->target = q;
+ i->methodIndex = methodCount + subIndex;
}
}
-inline void subscribe(QObject *o, int notifyIndex,
- int subIndex, QmlBindingVME::Config *config)
+void QmlCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex)
{
- QmlBindingVME::Config::Subscription *sub = (config->subscriptions + subIndex);
+ Q_Q(QmlCompiledBindings);
+
+ QmlCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
if (sub->isId())
- unsubscribe(subIndex, config);
+ unsubscribe(subIndex);
- QmlBindingVME::Config::Subscription::Signal *s = sub->signal();
+ QmlCompiledBindingsPrivate::Subscription::Signal *s = sub->signal();
if (o != s->source || notifyIndex != s->notifyIndex) {
if (s->source)
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
QMetaObject::disconnectOne(s->source, s->notifyIndex,
- config->target, config->targetSlot + subIndex);
+ q, methodCount + subIndex);
#else
// QTBUG-6781
QMetaObject::disconnect(s->source, s->notifyIndex,
- config->target, config->targetSlot + subIndex);
+ q, methodCount + subIndex);
#endif
s->source = o;
s->notifyIndex = notifyIndex;
if (s->source && s->notifyIndex != -1)
- QMetaObject::connect(s->source, s->notifyIndex, config->target,
- config->targetSlot + subIndex, Qt::DirectConnection);
+ QMetaObject::connect(s->source, s->notifyIndex, q,
+ methodCount + subIndex, Qt::DirectConnection);
}
}
@@ -566,10 +807,11 @@ static QObject *variantToQObject(const QVariant &value, bool *ok)
}
}
-static QmlPropertyCache::Data *findproperty(QObject *obj,
- const QScriptDeclarativeClass::Identifier &name,
- QmlEnginePrivate *enginePriv,
- QmlPropertyCache::Data &local)
+QmlPropertyCache::Data *
+QmlCompiledBindingsPrivate::findproperty(QObject *obj,
+ const QScriptDeclarativeClass::Identifier &name,
+ QmlEnginePrivate *enginePriv,
+ QmlPropertyCache::Data &local)
{
QmlPropertyCache *cache = 0;
QmlDeclarativeData *ddata = QmlDeclarativeData::get(obj);
@@ -595,11 +837,10 @@ static QmlPropertyCache::Data *findproperty(QObject *obj,
return property;
}
-static bool findproperty(QObject *obj, Register *output,
- QmlEnginePrivate *enginePriv,
- QmlBindingVME::Config *config, int subIdx,
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
+bool QmlCompiledBindingsPrivate::findproperty(QObject *obj, Register *output,
+ QmlEnginePrivate *enginePriv,
+ int subIdx, const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal)
{
if (!obj) {
output->setUndefined();
@@ -611,7 +852,7 @@ static bool findproperty(QObject *obj, Register *output,
if (property) {
if (subIdx != -1)
- subscribe(obj, property->notifyIndex, subIdx, config);
+ subscribe(obj, property->notifyIndex, subIdx);
if (property->flags & QmlPropertyCache::Data::IsQObjectDerived) {
void *args[] = { output->typeDataPtr(), 0 };
@@ -668,12 +909,11 @@ static bool findproperty(QObject *obj, Register *output,
}
}
-static void findgeneric(Register *output, // value output
- QmlBindingVME::Config *config,
- int subIdx, // Subscription index in config
- QmlContextPrivate *context, // Context to search in
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
+void QmlCompiledBindingsPrivate::findgeneric(Register *output,
+ int subIdx,
+ QmlContextPrivate *context,
+ const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal)
{
QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context->engine);
@@ -685,8 +925,7 @@ static void findgeneric(Register *output, // val
if (contextPropertyIndex != -1) {
if (subIdx != -1)
- subscribe(QmlContextPrivate::get(context), contextPropertyIndex + context->notifyIndex,
- subIdx, config);
+ subscribe(QmlContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx);
if (contextPropertyIndex < context->idValueCount) {
output->setQObject(context->idValues[contextPropertyIndex]);
@@ -717,7 +956,7 @@ static void findgeneric(Register *output, // val
if (QObject *root = context->defaultObjects.isEmpty()?0:context->defaultObjects.first()) {
- if (findproperty(root, output, enginePriv, config, subIdx, name, isTerminal))
+ if (findproperty(root, output, enginePriv, subIdx, name, isTerminal))
return;
}
@@ -732,20 +971,16 @@ static void findgeneric(Register *output, // val
output->setUndefined();
}
-/*!
-Returns the signal/binding table.
-*/
-void QmlBindingVME::init(const char *programData, Config *config,
- quint32 **sigTable, quint32 *bindingCount)
+void QmlCompiledBindingsPrivate::init()
{
Program *program = (Program *)programData;
if (program->subscriptions)
- config->subscriptions = new Config::Subscription[program->subscriptions];
+ subscriptions = new QmlCompiledBindingsPrivate::Subscription[program->subscriptions];
if (program->identifiers)
- config->identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers];
+ identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers];
- *sigTable = (quint32 *)(program->data() + program->signalTableOffset);
- *bindingCount = program->bindings;
+ m_signalTable = (quint32 *)(program->data() + program->signalTableOffset);
+ m_bindings = new QmlCompiledBindingsPrivate::Binding[program->bindings];
}
static void throwException(int id, QmlDelayedError *error,
@@ -769,9 +1004,9 @@ static void throwException(int id, QmlDelayedError *error,
qWarning() << error->error;
}
-void QmlBindingVME::run(const char *programData, int instrIndex,
- Config *config, QmlContextPrivate *context, QmlDelayedError *error,
- QObject *scope, QObject *output)
+void QmlCompiledBindingsPrivate::run(int instrIndex,
+ QmlContextPrivate *context, QmlDelayedError *error,
+ QObject *scope, QObject *output)
{
error->removeError();
@@ -791,17 +1026,15 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
break;
case Instr::SubscribeId:
- subscribeId(context, instr->subscribe.index, instr->subscribe.offset, config);
+ subscribeId(context, instr->subscribe.index, instr->subscribe.offset);
break;
case Instr::Subscribe:
{
QObject *o = 0;
- int notifyIndex = instr->subscribe.index;
-
const Register &object = registers[instr->subscribe.reg];
if (!object.isUndefined()) o = object.getQObject();
- subscribe(o, instr->subscribe.index, instr->subscribe.offset, config);
+ subscribe(o, instr->subscribe.index, instr->subscribe.offset);
}
break;
@@ -1084,14 +1317,13 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
return;
case Instr::InitString:
- if (!config->identifiers[instr->initstring.offset].identifier) {
+ if (!identifiers[instr->initstring.offset].identifier) {
quint32 len = *(quint32 *)(data + instr->initstring.dataIdx);
QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32));
QString str = QString::fromRawData(strdata, len);
- config->identifiers[instr->initstring.offset] =
- engine->objectClass->createPersistentIdentifier(str);
+ identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str);
}
break;
@@ -1100,9 +1332,9 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
// We start the search in the parent context, as we know that the
// name is not present in the current context or it would have been
// found during the static compile
- findgeneric(registers + instr->find.reg, config, instr->find.subscribeIndex,
+ findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
QmlContextPrivate::get(context->parent),
- config->identifiers[instr->find.name].identifier,
+ identifiers[instr->find.name].identifier,
instr->common.type == Instr::FindGenericTerminal);
break;
@@ -1116,8 +1348,8 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
}
findproperty(object.getQObject(), registers + instr->find.reg,
- QmlEnginePrivate::get(context->engine), config,
- instr->find.subscribeIndex, config->identifiers[instr->find.name].identifier,
+ QmlEnginePrivate::get(context->engine),
+ instr->find.subscribeIndex, identifiers[instr->find.name].identifier,
instr->common.type == Instr::FindPropertyTerminal);
}
break;
@@ -1186,9 +1418,9 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
}
}
-void QmlBindingVME::dump(const char *programData)
+void QmlBindingCompiler::dump(const QByteArray &programData)
{
- const Program *program = (const Program *)programData;
+ const Program *program = (const Program *)programData.constData();
qWarning() << "Program.bindings:" << program->bindings;
qWarning() << "Program.dataLength:" << program->dataLength;
@@ -2513,5 +2745,5 @@ QByteArray QmlBindingCompiler::program() const
}
-QT_END_NAMESPACE
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlbindingoptimizations_p.h b/src/declarative/qml/qmlcompiledbindings_p.h
index 42b7d17..1d8fac4 100644
--- a/src/declarative/qml/qmlbindingoptimizations_p.h
+++ b/src/declarative/qml/qmlcompiledbindings_p.h
@@ -55,50 +55,57 @@
#include "qmlexpression_p.h"
#include "qmlbinding.h"
-#include "qmlbindingvme_p.h"
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QmlOptimizedBindings : public QObject, public QmlAbstractExpression, public QmlRefCount
+class QmlBindingCompilerPrivate;
+class QmlBindingCompiler
{
public:
- QmlOptimizedBindings(const char *program, QmlContext *context);
- virtual ~QmlOptimizedBindings();
+ QmlBindingCompiler();
+ ~QmlBindingCompiler();
+
+ // Returns true if bindings were compiled
+ bool isValid() const;
+
+ struct Expression
+ {
+ QmlParser::Object *component;
+ QmlParser::Object *context;
+ QmlParser::Property *property;
+ QmlParser::Variant expression;
+ QHash<QString, QmlParser::Object *> ids;
+ QmlEnginePrivate::Imports imports;
+ };
+
+ // -1 on failure, otherwise the binding index to use
+ int compile(const Expression &, QmlEnginePrivate *);
+
+ // Returns the compiled program
+ QByteArray program() const;
+
+ static void dump(const QByteArray &);
+private:
+ QmlBindingCompilerPrivate *d;
+};
+
+class QmlCompiledBindingsPrivate;
+class QmlCompiledBindings : public QObject, public QmlAbstractExpression, public QmlRefCount
+{
+public:
+ QmlCompiledBindings(const char *program, QmlContext *context);
+ virtual ~QmlCompiledBindings();
+
QmlAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
protected:
int qt_metacall(QMetaObject::Call, int, void **);
private:
- struct Binding : public QmlAbstractBinding, public QmlDelayedError {
- Binding() : enabled(false), updating(0), property(0),
- scope(0), target(0), parent(0) {}
-
- // Inherited from QmlAbstractBinding
- virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags);
- virtual int propertyIndex();
- virtual void update(QmlMetaProperty::WriteFlags flags);
- virtual void destroy();
-
- int index:30;
- bool enabled:1;
- bool updating:1;
- int property;
- QObject *scope;
- QObject *target;
-
- QmlOptimizedBindings *parent;
- };
- void run(Binding *);
-
- QmlBindingVME::Config m_config;
- const char *m_program;
- Binding *m_bindings;
- quint32 *m_signalTable;
-
- static int methodCount;
+ Q_DISABLE_COPY(QmlCompiledBindings);
+ Q_DECLARE_PRIVATE(QmlCompiledBindings);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 5937734..2e18b85 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -64,7 +64,7 @@
#include "qmlglobal_p.h"
#include "qmlscriptparser_p.h"
#include "qmlbinding.h"
-#include "qmlbindingvme_p.h"
+#include "qmlcompiledbindings_p.h"
#include <qfxperf_p_p.h>
@@ -2672,7 +2672,7 @@ bool QmlCompiler::completeComponentBuild()
if (bindingCompiler.isValid()) {
compileState.compiledBindingData = bindingCompiler.program();
- QmlBindingVME::dump(compileState.compiledBindingData);
+ QmlBindingCompiler::dump(compileState.compiledBindingData);
}
saveComponentState();
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index f97f142..0eb497d 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -45,7 +45,7 @@
#include "qmlexpression_p.h"
#include "qmlengine_p.h"
#include "qmlengine.h"
-#include "qmlbindingoptimizations_p.h"
+#include "qmlcompiledbindings_p.h"
#include "qmlinfo.h"
#include <qscriptengine.h>
@@ -108,7 +108,7 @@ void QmlContextPrivate::destroyed(ContextGuard *guard)
while(guard->bindings) {
QObject *o = guard->bindings->target;
int mi = guard->bindings->methodIndex;
- guard->bindings->reset();
+ guard->bindings->clear();
if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0);
}
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index ffb4298..cd7e1b6 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -59,7 +59,6 @@
#include "qmlengine_p.h"
#include "qmlintegercache_p.h"
#include "qmltypenamecache_p.h"
-#include "qmlbindingvme_p.h"
#include <QtCore/qhash.h>
#include <QtScript/qscriptvalue.h>
@@ -77,7 +76,7 @@ class QmlExpression;
class QmlExpressionPrivate;
class QmlAbstractExpression;
class QmlBinding_Id;
-class QmlOptimizedBindings;
+class QmlCompiledBindings;
class Q_DECLARATIVE_EXPORT QmlContextPrivate : public QObjectPrivate
{
@@ -114,15 +113,27 @@ public:
QmlDeclarativeData *contextObjects;
+ struct IdNotifier
+ {
+ inline IdNotifier();
+ inline ~IdNotifier();
+
+ inline void clear();
+
+ IdNotifier *next;
+ IdNotifier**prev;
+ QObject *target;
+ int methodIndex;
+ };
+
struct ContextGuard : public QmlGuard<QObject>
{
- ContextGuard() : priv(0), bindings(0) {}
+ inline ContextGuard();
+ inline ContextGuard &operator=(QObject *obj);
+ inline virtual void objectDestroyed(QObject *);
+
QmlContextPrivate *priv;
- QmlBindingVME::Config::Subscription::Id *bindings;
- ContextGuard &operator=(QObject *obj) {
- (QmlGuard<QObject>&)*this = obj; return *this;
- }
- void objectDestroyed(QObject *) { priv->destroyed(this); }
+ IdNotifier *bindings;
};
ContextGuard *idValues;
int idValueCount;
@@ -137,12 +148,45 @@ public:
return static_cast<QmlContext *>(context->q_func());
}
- QmlOptimizedBindings *optimizedBindings;
+ QmlCompiledBindings *optimizedBindings;
// Only used for debugging
QList<QPointer<QObject> > instances;
};
+QmlContextPrivate::IdNotifier::IdNotifier()
+: next(0), prev(0), target(0), methodIndex(-1)
+{
+}
+
+QmlContextPrivate::IdNotifier::~IdNotifier()
+{
+ clear();
+}
+
+void QmlContextPrivate::IdNotifier::clear()
+{
+ if (next) next->prev = prev;
+ if (prev) *prev = next;
+ next = 0; prev = 0; target = 0;
+ methodIndex = -1;
+}
+
+QmlContextPrivate::ContextGuard::ContextGuard()
+: priv(0), bindings(0)
+{
+}
+
+QmlContextPrivate::ContextGuard &QmlContextPrivate::ContextGuard::operator=(QObject *obj)
+{
+ (QmlGuard<QObject>&)*this = obj; return *this;
+}
+
+void QmlContextPrivate::ContextGuard::objectDestroyed(QObject *)
+{
+ priv->destroyed(this);
+}
+
QT_END_NAMESPACE
#endif // QMLCONTEXT_P_H
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 6b2e7af..e9a0449 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -57,7 +57,7 @@
#include "qmlvmemetaobject_p.h"
#include "qmlbinding_p.h"
#include "qmlcontext_p.h"
-#include "qmlbindingoptimizations_p.h"
+#include "qmlcompiledbindings_p.h"
#include "qmlglobal_p.h"
#include "qmlscriptstring.h"
@@ -173,7 +173,7 @@ QObject *QmlVME::run(QmlVMEStack<QObject *> &stack, QmlContext *ctxt,
if (instr.init.contextCache != -1)
cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
if (instr.init.compiledBinding != -1)
- cp->optimizedBindings = new QmlOptimizedBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
+ cp->optimizedBindings = new QmlCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
}
break;