aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-07-13 14:12:21 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-30 13:18:28 +0200
commit3d958cec8d53094a1bbab895377e451b07716e1f (patch)
treeb034627cbf58a88773984b74f3437008344b25e0 /src
parentf68290cb245ecddaa720ff6853511259e449e568 (diff)
Use memory more conservatively during QML compilation
Change-Id: I63af79e575345bce00d724f1e7c87606156d1479 Reviewed-on: http://codereview.qt.nokia.com/3744 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/ftw/ftw.pri3
-rw-r--r--src/declarative/qml/ftw/qdeclarativepool.cpp92
-rw-r--r--src/declarative/qml/ftw/qdeclarativepool_p.h200
-rw-r--r--src/declarative/qml/ftw/qfieldlist_p.h210
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp614
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h193
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp14
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp156
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h298
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp102
-rw-r--r--src/declarative/qml/qdeclarativescriptparser_p.h5
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp2
13 files changed, 1242 insertions, 649 deletions
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
index 8709363363..000c81b83b 100644
--- a/src/declarative/qml/ftw/ftw.pri
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -7,10 +7,13 @@ HEADERS += \
$$PWD/qpodvector_p.h \
$$PWD/qhashedstring_p.h \
$$PWD/qdeclarativerefcount_p.h \
+ $$PWD/qdeclarativepool_p.h \
+ $$PWD/qfieldlist_p.h \
SOURCES += \
$$PWD/qintrusivelist.cpp \
$$PWD/qmetaobjectbuilder.cpp \
$$PWD/qhashedstring.cpp \
$$PWD/qdeclarativerefcount.cpp \
+ $$PWD/qdeclarativepool.cpp \
diff --git a/src/declarative/qml/ftw/qdeclarativepool.cpp b/src/declarative/qml/ftw/qdeclarativepool.cpp
new file mode 100644
index 0000000000..94bb89bd46
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativepool.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "qdeclarativepool_p.h"
+
+// #define POOL_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+void QDeclarativePool::newpage()
+{
+#ifdef POOL_DEBUG
+ qWarning("QDeclarativePool: Allocating page");
+#endif
+
+ Page *page = (Page *)malloc(sizeof(Page));
+ page->header.next = _page;
+ page->header.free = page->memory;
+ _page = page;
+}
+
+void QDeclarativePool::clear()
+{
+#ifdef POOL_DEBUG
+ int count = 0;
+#endif
+
+ Class *c = _classList;
+ while (c) {
+ Class *n = c->_next;
+ c->_destroy(c);
+#ifdef POOL_DEBUG
+ ++count;
+#endif
+ c = n;
+ }
+
+#ifdef POOL_DEBUG
+ qWarning("QDeclarativePool: Destroyed %d objects", count);
+#endif
+
+ Page *p = _page;
+ while (p) {
+ Page *n = p->header.next;
+ free(p);
+ p = n;
+ }
+
+ _classList = 0;
+ _page = 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qdeclarativepool_p.h b/src/declarative/qml/ftw/qdeclarativepool_p.h
new file mode 100644
index 0000000000..a087779b1e
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativepool_p.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QDECLARATIVEPOOL_P_H
+#define QDECLARATIVEPOOL_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 <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativePool
+{
+public:
+ // The class has a destructor that needs to be called
+ class Class {
+ public:
+ inline QDeclarativePool *pool() const;
+
+ private:
+ void *operator new(size_t);
+ void *operator new(size_t, void *m) { return m; }
+ friend class QDeclarativePool;
+
+ QDeclarativePool *_pool;
+ Class *_next;
+ void (*_destroy)(Class *);
+ };
+
+ // The class is plain old data and no destructor needs to
+ // be called
+ class POD {
+ public:
+ inline QDeclarativePool *pool() const;
+
+ private:
+ void *operator new(size_t);
+ void *operator new(size_t, void *m) { return m; }
+ friend class QDeclarativePool;
+
+ QDeclarativePool *_pool;
+ };
+
+ inline QDeclarativePool();
+ inline ~QDeclarativePool();
+
+ void clear();
+
+ template<typename T>
+ inline T *New();
+
+ inline QString *NewString(const QString &);
+
+private:
+ struct StringClass : public QString, public Class {
+ };
+
+ inline void *allocate(int size);
+ void newpage();
+
+ template<typename T>
+ inline void initialize(POD *);
+ template<typename T>
+ inline void initialize(Class *);
+ template<typename T>
+ static void destroy(Class *c);
+
+ struct Page {
+ struct Header {
+ Page *next;
+ char *free;
+ } header;
+
+ static const int pageSize = 4 * 4096 - sizeof(Header);
+
+ char memory[pageSize];
+ };
+
+ Page *_page;
+ Class *_classList;
+};
+
+QDeclarativePool::QDeclarativePool()
+: _page(0), _classList(0)
+{
+}
+
+QDeclarativePool::~QDeclarativePool()
+{
+ clear();
+}
+
+template<typename T>
+T *QDeclarativePool::New()
+{
+ T *rv = new (allocate(sizeof(T))) T;
+ initialize<T>(rv);
+ rv->_pool = this;
+ return rv;
+}
+
+QString *QDeclarativePool::NewString(const QString &s)
+{
+ QString *rv = New<StringClass>();
+ *rv = s;
+ return rv;
+}
+
+void *QDeclarativePool::allocate(int size)
+{
+ if (!_page || (_page->header.free + size) > (_page->memory + Page::pageSize))
+ newpage();
+
+ void *rv = _page->header.free;
+ _page->header.free += size + ((8 - size) & 7); // ensure 8 byte alignment;
+ return rv;
+}
+
+template<typename T>
+void QDeclarativePool::initialize(QDeclarativePool::POD *)
+{
+}
+
+template<typename T>
+void QDeclarativePool::initialize(QDeclarativePool::Class *c)
+{
+ c->_next = _classList;
+ c->_destroy = &destroy<T>;
+ _classList = c;
+}
+
+template<typename T>
+void QDeclarativePool::destroy(Class *c)
+{
+ static_cast<T *>(c)->~T();
+}
+
+QDeclarativePool *QDeclarativePool::Class::pool() const
+{
+ return _pool;
+}
+
+QDeclarativePool *QDeclarativePool::POD::pool() const
+{
+ return _pool;
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEPOOL_P_H
+
diff --git a/src/declarative/qml/ftw/qfieldlist_p.h b/src/declarative/qml/ftw/qfieldlist_p.h
new file mode 100644
index 0000000000..65b1d4b4ee
--- /dev/null
+++ b/src/declarative/qml/ftw/qfieldlist_p.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QFIELDLIST_P_H
+#define QFIELDLIST_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>
+
+template<class N, N *N::*nextMember>
+class QFieldList
+{
+public:
+ inline QFieldList();
+ inline N *first() const;
+ inline void append(N *);
+ inline void prepend(N *);
+
+ inline bool isEmpty() const;
+ inline bool isOne() const;
+ inline bool isMany() const;
+ inline int count() const;
+
+ inline void append(QFieldList<N, nextMember> &);
+ inline void prepend(QFieldList<N, nextMember> &);
+ inline void insertAfter(N *, QFieldList<N, nextMember> &);
+
+ static inline N *next(N *v);
+
+private:
+ N *_first;
+ N *_last;
+ int _count;
+};
+
+template<class N, N *N::*nextMember>
+QFieldList<N, nextMember>::QFieldList()
+: _first(0), _last(0), _count(0)
+{
+}
+
+template<class N, N *N::*nextMember>
+N *QFieldList<N, nextMember>::first() const
+{
+ return _first;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::append(N *v)
+{
+ Q_ASSERT(v->*nextMember == 0);
+ if (isEmpty()) {
+ _first = v;
+ _last = v;
+ } else {
+ _last->*nextMember = v;
+ _last = v;
+ }
+ ++_count;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::prepend(N *v)
+{
+ Q_ASSERT(v->*nextMember == 0);
+ if (isEmpty()) {
+ _first = v;
+ _last = v;
+ } else {
+ v->*nextMember = _first;
+ _first = v;
+ }
+ ++_count;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isEmpty() const
+{
+ return _count == 0;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isOne() const
+{
+ return _count == 1;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isMany() const
+{
+ return _count > 1;
+}
+
+template<class N, N *N::*nextMember>
+int QFieldList<N, nextMember>::count() const
+{
+ return _count;
+}
+
+template<class N, N *N::*nextMember>
+N *QFieldList<N, nextMember>::next(N *v)
+{
+ Q_ASSERT(v);
+ return v->*nextMember;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::append(QFieldList<N, nextMember> &o)
+{
+ if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ _last->*nextMember = o._first;
+ _last = o._last;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::prepend(QFieldList<N, nextMember> &o)
+{
+ if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ o._last->*nextMember = _first;
+ _first = o._first;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::insertAfter(N *after, QFieldList<N, nextMember> &o)
+{
+ if (after == 0) {
+ prepend(o);
+ } else if (after == _last) {
+ append(o);
+ } else if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ o._last->*nextMember = after->*nextMember;
+ after->*nextMember = o._first;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+#endif // QFIELDLIST_P_H
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.h b/src/declarative/qml/parser/qdeclarativejsengine_p.h
index e366e8b9b3..fd07f3fe3c 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.h
@@ -71,7 +71,7 @@ public:
: _text(u, s)
{ }
- const QString asString() const
+ const QString &asString() const
{ return _text; }
bool operator == (const NameId &other) const
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index aa7e07fcad..543ecb24b3 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -80,6 +80,7 @@ DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
using namespace QDeclarativeParser;
+using namespace QDeclarativeCompilerTypes;
static QString id_string(QLatin1String("id"));
static QString on_string(QLatin1String("on"));
@@ -89,9 +90,11 @@ static QString Component_string(QLatin1String("Component"));
/*!
Instantiate a new QDeclarativeCompiler.
*/
-QDeclarativeCompiler::QDeclarativeCompiler()
-: output(0), engine(0), unitRoot(0), unit(0)
+QDeclarativeCompiler::QDeclarativeCompiler(QDeclarativePool *pool)
+: pool(pool), output(0), engine(0), unitRoot(0), unit(0), componentStats(0)
{
+ if (compilerStatDump())
+ componentStats = pool->New<ComponentStats>();
}
/*!
@@ -195,18 +198,18 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QString &name)
bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
QDeclarativeParser::Value *v)
{
- QString string = v->value.asString();
+ const QDeclarativeParser::Variant &value = v->value;
if (!prop.isWritable())
COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
if (prop.isEnumType()) {
- int value;
+ int enumValue;
if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(string.toUtf8().constData());
+ enumValue = prop.enumerator().keysToValue(value.asString().toUtf8().constData());
} else
- value = prop.enumerator().keyToValue(string.toUtf8().constData());
- if (value == -1)
+ enumValue = prop.enumerator().keyToValue(value.asString().toUtf8().constData());
+ if (enumValue == -1)
COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration"));
return true;
}
@@ -254,7 +257,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Color:
{
bool ok;
- QDeclarativeStringConverters::colorFromString(string, &ok);
+ QDeclarativeStringConverters::colorFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
}
break;
@@ -262,21 +265,21 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Date:
{
bool ok;
- QDeclarativeStringConverters::dateFromString(string, &ok);
+ QDeclarativeStringConverters::dateFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
}
break;
case QVariant::Time:
{
bool ok;
- QDeclarativeStringConverters::timeFromString(string, &ok);
+ QDeclarativeStringConverters::timeFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: time expected"));
}
break;
case QVariant::DateTime:
{
bool ok;
- QDeclarativeStringConverters::dateTimeFromString(string, &ok);
+ QDeclarativeStringConverters::dateTimeFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
}
break;
@@ -285,7 +288,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::PointF:
{
bool ok;
- QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+ QPointF point = QDeclarativeStringConverters::pointFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: point expected"));
}
break;
@@ -293,7 +296,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::SizeF:
{
bool ok;
- QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
+ QSizeF size = QDeclarativeStringConverters::sizeFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: size expected"));
}
break;
@@ -301,7 +304,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::RectF:
{
bool ok;
- QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
+ QRectF rect = QDeclarativeStringConverters::rectFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: rect expected"));
}
break;
@@ -313,7 +316,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Vector3D:
{
bool ok;
- QDeclarativeStringConverters::vector3DFromString(string, &ok);
+ QDeclarativeStringConverters::vector3DFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected"));
}
break;
@@ -367,8 +370,6 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
return;
}
- QString string = v->value.asString();
-
int type = prop.userType();
switch(type) {
case -1:
@@ -391,7 +392,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
} else {
instr.setType(QDeclarativeInstruction::StoreVariant);
instr.storeString.propertyIndex = prop.propertyIndex();
- instr.storeString.value = output->indexForString(string);
+ instr.storeString.value = output->indexForString(v->value.asString());
}
}
break;
@@ -399,19 +400,20 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
{
instr.setType(QDeclarativeInstruction::StoreString);
instr.storeString.propertyIndex = prop.propertyIndex();
- instr.storeString.value = output->indexForString(string);
+ instr.storeString.value = output->indexForString(v->value.asString());
}
break;
case QVariant::ByteArray:
{
instr.setType(QDeclarativeInstruction::StoreByteArray);
instr.storeByteArray.propertyIndex = prop.propertyIndex();
- instr.storeByteArray.value = output->indexForByteArray(string.toLatin1());
+ instr.storeByteArray.value = output->indexForByteArray(v->value.asString().toLatin1());
}
break;
case QVariant::Url:
{
instr.setType(QDeclarativeInstruction::StoreUrl);
+ QString string = v->value.asString();
QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
instr.storeUrl.propertyIndex = prop.propertyIndex();
instr.storeUrl.value = output->indexForUrl(u);
@@ -447,7 +449,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
case QVariant::Color:
{
- QColor c = QDeclarativeStringConverters::colorFromString(string);
+ QColor c = QDeclarativeStringConverters::colorFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreColor);
instr.storeColor.propertyIndex = prop.propertyIndex();
instr.storeColor.value = c.rgba();
@@ -456,7 +458,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
#ifndef QT_NO_DATESTRING
case QVariant::Date:
{
- QDate d = QDeclarativeStringConverters::dateFromString(string);
+ QDate d = QDeclarativeStringConverters::dateFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreDate);
instr.storeDate.propertyIndex = prop.propertyIndex();
instr.storeDate.value = d.toJulianDay();
@@ -464,7 +466,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
case QVariant::Time:
{
- QTime time = QDeclarativeStringConverters::timeFromString(string);
+ QTime time = QDeclarativeStringConverters::timeFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreTime);
instr.storeTime.propertyIndex = prop.propertyIndex();
Q_ASSERT(sizeof(instr.storeTime.time) == sizeof(QTime));
@@ -473,7 +475,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
case QVariant::DateTime:
{
- QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(string);
+ QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(v->value.asString());
QTime time = dateTime.time();
instr.setType(QDeclarativeInstruction::StoreDateTime);
instr.storeDateTime.propertyIndex = prop.propertyIndex();
@@ -486,7 +488,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Point:
{
bool ok;
- QPoint point = QDeclarativeStringConverters::pointFFromString(string, &ok).toPoint();
+ QPoint point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok).toPoint();
instr.setType(QDeclarativeInstruction::StorePoint);
instr.storePoint.propertyIndex = prop.propertyIndex();
instr.storePoint.point.xp = point.x();
@@ -496,7 +498,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::PointF:
{
bool ok;
- QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+ QPointF point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StorePointF);
instr.storePointF.propertyIndex = prop.propertyIndex();
instr.storePointF.point.xp = point.x();
@@ -506,7 +508,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Size:
{
bool ok;
- QSize size = QDeclarativeStringConverters::sizeFFromString(string, &ok).toSize();
+ QSize size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok).toSize();
instr.setType(QDeclarativeInstruction::StoreSize);
instr.storeSize.propertyIndex = prop.propertyIndex();
instr.storeSize.size.wd = size.width();
@@ -516,7 +518,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::SizeF:
{
bool ok;
- QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
+ QSizeF size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreSizeF);
instr.storeSizeF.propertyIndex = prop.propertyIndex();
instr.storeSizeF.size.wd = size.width();
@@ -526,7 +528,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Rect:
{
bool ok;
- QRect rect = QDeclarativeStringConverters::rectFFromString(string, &ok).toRect();
+ QRect rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok).toRect();
instr.setType(QDeclarativeInstruction::StoreRect);
instr.storeRect.propertyIndex = prop.propertyIndex();
instr.storeRect.rect.x1 = rect.left();
@@ -538,7 +540,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::RectF:
{
bool ok;
- QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
+ QRectF rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreRectF);
instr.storeRectF.propertyIndex = prop.propertyIndex();
instr.storeRectF.rect.xp = rect.left();
@@ -558,7 +560,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Vector3D:
{
bool ok;
- QVector3D vector = QDeclarativeStringConverters::vector3DFromString(string, &ok);
+ QVector3D vector = QDeclarativeStringConverters::vector3DFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreVector3D);
instr.storeVector3D.propertyIndex = prop.propertyIndex();
instr.storeVector3D.vector.xp = vector.x();
@@ -583,7 +585,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
int t = prop.userType();
instr.setType(QDeclarativeInstruction::AssignCustomType);
instr.assignCustomType.propertyIndex = prop.propertyIndex();
- instr.assignCustomType.primitive = output->indexForString(string);
+ instr.assignCustomType.primitive = output->indexForString(v->value.asString());
instr.assignCustomType.type = t;
}
break;
@@ -673,15 +675,14 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
if (!isError()) {
if (compilerDump())
out->dumpInstructions();
- if (compilerStatDump())
+ if (componentStats)
dumpStats();
Q_ASSERT(out->rootPropertyCache);
} else {
reset(out);
}
- compileState = ComponentCompileState();
- savedCompileStates.clear();
+ compileState = 0;
output = 0;
this->engine = 0;
this->enginePrivate = 0;
@@ -693,8 +694,11 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
{
- compileState.root = tree;
- componentStat.lineNumber = tree->location.start.line;
+ compileState = pool->New<ComponentCompileState>();
+
+ compileState->root = tree;
+ if (componentStats)
+ componentStats->componentStat.lineNumber = tree->location.start.line;
// Build global import scripts
QStringList importedScriptIndexes;
@@ -725,21 +729,21 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count();
- init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.bindingsSize = compileState->bindings.count();
+ init.init.parserStatusSize = compileState->parserStatusCount;
init.init.contextCache = genContextCache();
- if (compileState.compiledBindingData.isEmpty())
+ if (compileState->compiledBindingData.isEmpty())
init.init.compiledBinding = -1;
else
- init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+ init.init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
output->addInstruction(init);
- if (!compileState.v8BindingProgram.isEmpty()) {
+ if (!compileState->v8BindingProgram.isEmpty()) {
QDeclarativeInstruction bindings;
bindings.setType(QDeclarativeInstruction::InitV8Bindings);
- bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
- bindings.initV8Bindings.programIndex = compileState.v8BindingProgramIndex;
- bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+ bindings.initV8Bindings.program = output->indexForString(compileState->v8BindingProgram);
+ bindings.initV8Bindings.programIndex = compileState->v8BindingProgramIndex;
+ bindings.initV8Bindings.line = compileState->v8BindingProgramLine;
output->addInstruction(bindings);
}
@@ -765,16 +769,10 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
enginePrivate->registerCompositeType(output);
}
-static bool ValuePtrLessThan(const QDeclarativeParser::Value *t1, const QDeclarativeParser::Value *t2)
-{
- return t1->location.start.line < t2->location.start.line ||
- (t1->location.start.line == t2->location.start.line &&
- t1->location.start.column < t2->location.start.column);
-}
-
bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt)
{
- componentStat.objects++;
+ if (componentStats)
+ componentStats->componentStat.objects++;
Q_ASSERT (obj->type != -1);
const QDeclarativeCompiledData::TypeReference &tr =
@@ -803,7 +801,7 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
Q_ASSERT(type);
obj->parserStatusCast = type->parserStatusCast();
if (obj->parserStatusCast != -1)
- compileState.parserStatusCount++;
+ compileState->parserStatusCount++;
// Check if this is a custom parser type. Custom parser types allow
// assignments to non-existent properties. These assignments are then
@@ -818,8 +816,8 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
// Must do id property first. This is to ensure that the id given to any
// id reference created matches the order in which the objects are
// instantiated
- foreach(Property *prop, obj->properties) {
- if (prop->name == id_string) {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+ if (prop->name() == id_string) {
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
break;
}
@@ -829,33 +827,29 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
Property *defaultProperty = 0;
Property *skipProperty = 0;
if (obj->defaultProperty) {
+ defaultProperty = obj->defaultProperty;
+
const QMetaObject *metaObject = obj->metaObject();
Q_ASSERT(metaObject);
QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
if (p.name()) {
- Property *explicitProperty = obj->getProperty(p.name(), false);
- if (explicitProperty && !explicitProperty->value) {
- skipProperty = explicitProperty;
-
- defaultProperty = new Property;
- defaultProperty->parent = obj;
- defaultProperty->isDefault = true;
- defaultProperty->location = obj->defaultProperty->location;
- defaultProperty->listValueRange = obj->defaultProperty->listValueRange;
-
- defaultProperty->values = obj->defaultProperty->values;
- defaultProperty->values += explicitProperty->values;
- foreach(QDeclarativeParser::Value *value, defaultProperty->values)
- value->addref();
- qSort(defaultProperty->values.begin(), defaultProperty->values.end(), ValuePtrLessThan);
+ Property *explicitProperty = obj->getProperty(QString::fromUtf8(p.name()), false);
+ if (explicitProperty && !explicitProperty->value && !explicitProperty->values.isEmpty()) {
- } else {
- defaultProperty = obj->defaultProperty;
- defaultProperty->addref();
- }
- } else {
- defaultProperty = obj->defaultProperty;
- defaultProperty->addref();
+ skipProperty = explicitProperty; // We merge the values into defaultProperty
+
+ // Find the correct insertion point
+ Value *insertPos = 0;
+
+ for (Value *v = defaultProperty->values.first(); v; v = Property::ValueList::next(v)) {
+ if (!(v->location.start < explicitProperty->values.first()->location.start))
+ break;
+ insertPos = v;
+ }
+
+ defaultProperty->values.insertAfter(insertPos, explicitProperty->values);
+
+ }
}
}
@@ -864,38 +858,38 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
cp = output->types.at(obj->type).type->customParser();
// Build all explicit properties specified
- foreach(Property *prop, obj->properties) {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
if (prop == skipProperty)
continue;
- if (prop->name == id_string)
+ if (prop->name() == id_string)
continue;
bool canDefer = false;
if (isCustomParser) {
- if (doesPropertyExist(prop, obj) &&
+ if (doesPropertyExist(prop, obj) &&
(!(cp->flags() & QDeclarativeCustomParser::AcceptsAttachedProperties) ||
- !isAttachedPropertyName(prop->name))) {
- int ids = compileState.ids.count();
+ !isAttachedPropertyName(prop->name()))) {
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
- } else if (isSignalPropertyName(prop->name) &&
+ canDefer = ids == compileState->ids.count();
+ } else if (isSignalPropertyName(prop->name()) &&
(cp->flags() & QDeclarativeCustomParser::AcceptsSignalHandlers)) {
COMPILE_CHECK(buildSignal(prop,obj,objCtxt));
} else {
customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop);
}
} else {
- if (isSignalPropertyName(prop->name)) {
+ if (isSignalPropertyName(prop->name())) {
COMPILE_CHECK(buildSignal(prop,obj,objCtxt));
} else {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
}
}
- if (canDefer && !deferredList.isEmpty() && deferredList.contains(prop->name))
+ if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name()))
prop->isDeferred = true;
}
@@ -907,25 +901,22 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
bool canDefer = false;
if (isCustomParser) {
if (doesPropertyExist(prop, obj)) {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
} else {
customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop);
}
} else {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
}
- if (canDefer && !deferredList.isEmpty() && deferredList.contains(prop->name))
+ if (canDefer && !deferredList.isEmpty() && deferredList.contains(prop->name()))
prop->isDeferred = true;
}
- if (defaultProperty)
- defaultProperty->release();
-
// Compile custom parser parts
if (isCustomParser && !customProps.isEmpty()) {
cp->clearErrors();
@@ -953,7 +944,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
// Create the object
if (obj->custom.isEmpty() && output->types.at(obj->type).type &&
- !output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) {
+ !output->types.at(obj->type).type->isExtendedType() && obj != compileState->root) {
QDeclarativeInstruction create;
create.setType(QDeclarativeInstruction::CreateSimpleObject);
@@ -1043,21 +1034,21 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
{
- typedef QPair<Property *, int> PropPair;
- foreach(const PropPair &prop, obj->scriptStringProperties) {
- const QString &script = prop.first->values.at(0)->value.asScript();
+ for (Property *prop = obj->scriptStringProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
+ Q_ASSERT(prop->scriptStringScope != -1);
+ const QString &script = prop->values.first()->value.asScript();
QDeclarativeInstruction ss;
ss.setType(QDeclarativeInstruction::StoreScriptString);
- ss.storeScriptString.propertyIndex = prop.first->index;
+ ss.storeScriptString.propertyIndex = prop->index;
ss.storeScriptString.value = output->indexForString(script);
- ss.storeScriptString.scope = prop.second;
- ss.storeScriptString.bindingId = rewriteBinding(script, prop.first->name);
- ss.storeScriptString.line = prop.first->location.start.line;
+ ss.storeScriptString.scope = prop->scriptStringScope;
+ ss.storeScriptString.bindingId = rewriteBinding(script, prop->name());
+ ss.storeScriptString.line = prop->location.start.line;
output->addInstruction(ss);
}
bool seenDefer = false;
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isDeferred) {
seenDefer = true;
continue;
@@ -1074,13 +1065,13 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count(); // XXX - bigger than necessary
- init.init.parserStatusSize = compileState.parserStatusCount; // XXX - bigger than necessary
+ init.init.bindingsSize = compileState->bindings.count(); // XXX - bigger than necessary
+ init.init.parserStatusSize = compileState->parserStatusCount; // XXX - bigger than necessary
init.init.contextCache = -1;
init.init.compiledBinding = -1;
output->addInstruction(init);
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (!prop->isDeferred)
continue;
genValueProperty(prop, obj);
@@ -1093,9 +1084,9 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->instruction(deferIdx)->defer.deferCount = output->nextInstructionIndex() - nextInstructionIndex;
}
- foreach(Property *prop, obj->signalProperties) {
+ for (Property *prop = obj->signalProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
- QDeclarativeParser::Value *v = prop->values.at(0);
+ QDeclarativeParser::Value *v = prop->values.first();
if (v->type == Value::SignalObject) {
@@ -1105,12 +1096,12 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
assign.setType(QDeclarativeInstruction::AssignSignalObject);
assign.assignSignalObject.line = v->location.start.line;
assign.assignSignalObject.signal =
- output->indexForString(prop->name);
+ output->indexForString(prop->name());
output->addInstruction(assign);
} else if (v->type == Value::SignalExpression) {
- BindingContext ctxt = compileState.signalExpressions.value(v);
+ BindingContext ctxt = compileState->signalExpressions.value(v);
QDeclarativeInstruction store;
store.setType(QDeclarativeInstruction::StoreSignal);
@@ -1118,7 +1109,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
store.storeSignal.value =
output->indexForString(v->value.asScript().trimmed());
store.storeSignal.context = ctxt.stack;
- store.storeSignal.name = output->indexForByteArray(prop->name.toUtf8());
+ store.storeSignal.name = output->indexForByteArray(prop->name().toUtf8());
store.storeSignal.line = v->location.start.line;
output->addInstruction(store);
@@ -1126,7 +1117,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
}
- foreach(Property *prop, obj->attachedProperties) {
+ for (Property *prop = obj->attachedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
QDeclarativeInstruction fetch;
fetch.setType(QDeclarativeInstruction::FetchAttached);
fetch.fetchAttached.id = prop->index;
@@ -1140,7 +1131,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->addInstruction(pop);
}
- foreach(Property *prop, obj->groupedProperties) {
+ for (Property *prop = obj->groupedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
QDeclarativeInstruction fetch;
fetch.setType(QDeclarativeInstruction::FetchObject);
fetch.fetch.property = prop->index;
@@ -1163,19 +1154,19 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->addInstruction(pop);
}
- foreach(Property *prop, obj->valueTypeProperties) {
+ for (Property *prop = obj->valueTypeProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (!prop->isAlias)
genValueTypeProperty(obj, prop);
}
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isDeferred)
continue;
if (prop->isAlias)
genValueProperty(prop, obj);
}
- foreach(Property *prop, obj->valueTypeProperties) {
+ for (Property *prop = obj->valueTypeProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isAlias)
genValueTypeProperty(obj, prop);
}
@@ -1192,7 +1183,7 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
if (obj->type == -1 || output->types.at(obj->type).component) {
// We only have to do this if this is a composite type. If it is a builtin
// type it can't possibly already have bindings that need to be cleared.
- foreach(Property *vprop, prop->value->valueProperties) {
+ for (Property *vprop = prop->value->valueProperties.first(); vprop; vprop = Object::PropertyList::next(vprop)) {
if (!vprop->values.isEmpty()) {
Q_ASSERT(vprop->index >= 0 && vprop->index < 32);
fetch.fetchValue.bindingSkipList |= (1 << vprop->index);
@@ -1202,7 +1193,7 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
output->addInstruction(fetch);
- foreach(Property *vprop, prop->value->valueProperties) {
+ for (Property *vprop = prop->value->valueProperties.first(); vprop; vprop = Object::PropertyList::next(vprop)) {
genPropertyAssignment(vprop, prop->value, prop);
}
@@ -1216,7 +1207,7 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
{
- QDeclarativeParser::Object *root = obj->defaultProperty->values.at(0)->object;
+ QDeclarativeParser::Object *root = obj->defaultProperty->values.first()->object;
Q_ASSERT(root);
QDeclarativeInstruction create;
@@ -1227,26 +1218,26 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
int createInstruction = output->addInstruction(create);
int nextInstructionIndex = output->nextInstructionIndex();
- ComponentCompileState oldCompileState = compileState;
+ ComponentCompileState *oldCompileState = compileState;
compileState = componentState(root);
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count();
- init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.bindingsSize = compileState->bindings.count();
+ init.init.parserStatusSize = compileState->parserStatusCount;
init.init.contextCache = genContextCache();
- if (compileState.compiledBindingData.isEmpty())
+ if (compileState->compiledBindingData.isEmpty())
init.init.compiledBinding = -1;
else
- init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+ init.init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
output->addInstruction(init);
- if (!compileState.v8BindingProgram.isEmpty()) {
+ if (!compileState->v8BindingProgram.isEmpty()) {
QDeclarativeInstruction bindings;
bindings.setType(QDeclarativeInstruction::InitV8Bindings);
- bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
- bindings.initV8Bindings.programIndex = compileState.v8BindingProgramIndex;
- bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+ bindings.initV8Bindings.program = output->indexForString(compileState->v8BindingProgram);
+ bindings.initV8Bindings.programIndex = compileState->v8BindingProgramIndex;
+ bindings.initV8Bindings.line = compileState->v8BindingProgramLine;
output->addInstruction(bindings);
}
@@ -1287,21 +1278,21 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
// Find, check and set the "id" property (if any)
Property *idProp = 0;
- if (obj->properties.count() > 1 ||
- (obj->properties.count() == 1 && obj->properties.begin().key() != id_string))
- COMPILE_EXCEPTION(*obj->properties.begin(), tr("Component elements may not contain properties other than id"));
+ if (obj->properties.isMany() ||
+ (obj->properties.isOne() && obj->properties.first()->name() != id_string))
+ COMPILE_EXCEPTION(obj->properties.first(), tr("Component elements may not contain properties other than id"));
- if (obj->properties.count())
- idProp = *obj->properties.begin();
+ if (!obj->properties.isEmpty())
+ idProp = obj->properties.first();
if (idProp) {
- if (idProp->value || idProp->values.count() > 1 || idProp->values.at(0)->object)
+ if (idProp->value || idProp->values.isMany() || idProp->values.first()->object)
COMPILE_EXCEPTION(idProp, tr("Invalid component id specification"));
COMPILE_CHECK(checkValidId(idProp->values.first(), idProp->values.first()->primitive()))
QString idVal = idProp->values.first()->primitive();
- if (compileState.ids.contains(idVal))
+ if (compileState->ids.contains(idVal))
COMPILE_EXCEPTION(idProp, tr("id is not unique"));
obj->id = idVal;
@@ -1310,8 +1301,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
// Check the Component tree is well formed
if (obj->defaultProperty &&
- (obj->defaultProperty->value || obj->defaultProperty->values.count() > 1 ||
- (obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
+ (obj->defaultProperty->value || obj->defaultProperty->values.isMany() ||
+ (obj->defaultProperty->values.isOne() && !obj->defaultProperty->values.first()->object)))
COMPILE_EXCEPTION(obj, tr("Invalid component body specification"));
if (!obj->dynamicProperties.isEmpty())
@@ -1322,7 +1313,7 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
QDeclarativeParser::Object *root = 0;
- if (obj->defaultProperty && obj->defaultProperty->values.count())
+ if (obj->defaultProperty && !obj->defaultProperty->values.isEmpty())
root = obj->defaultProperty->values.first()->object;
if (!root)
@@ -1337,23 +1328,31 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *obj,
const BindingContext &ctxt)
{
- ComponentCompileState oldComponentCompileState = compileState;
- ComponentStat oldComponentStat = componentStat;
+ ComponentCompileState *oldComponentCompileState = compileState;
+ compileState = pool->New<ComponentCompileState>();
+ compileState->root = obj;
+ compileState->nested = true;
- compileState = ComponentCompileState();
- compileState.root = obj;
- compileState.nested = true;
+ if (componentStats) {
+ ComponentStat oldComponentStat = componentStats->componentStat;
- componentStat = ComponentStat();
- componentStat.lineNumber = obj->location.start.line;
+ componentStats->componentStat = ComponentStat();
+ componentStats->componentStat.lineNumber = obj->location.start.line;
- if (obj)
- COMPILE_CHECK(buildObject(obj, ctxt));
+ if (obj)
+ COMPILE_CHECK(buildObject(obj, ctxt));
- COMPILE_CHECK(completeComponentBuild());
+ COMPILE_CHECK(completeComponentBuild());
+
+ componentStats->componentStat = oldComponentStat;
+ } else {
+ if (obj)
+ COMPILE_CHECK(buildObject(obj, ctxt));
+
+ COMPILE_CHECK(completeComponentBuild());
+ }
compileState = oldComponentCompileState;
- componentStat = oldComponentStat;
return true;
}
@@ -1369,8 +1368,8 @@ bool QDeclarativeCompiler::buildSubObject(QDeclarativeParser::Object *obj, const
Q_ASSERT(ctxt.isSubContext()); // sub-objects must always be in a binding
// sub-context
- foreach(Property *prop, obj->properties) {
- if (isSignalPropertyName(prop->name)) {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+ if (isSignalPropertyName(prop->name())) {
COMPILE_CHECK(buildSignal(prop, obj, ctxt));
} else {
COMPILE_CHECK(buildProperty(prop, obj, ctxt));
@@ -1399,7 +1398,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
{
Q_ASSERT(obj->metaObject());
- QString name = prop->name;
+ QString name = prop->name();
Q_ASSERT(name.startsWith(on_string));
name = name.mid(2);
@@ -1417,14 +1416,14 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
if (sigIdx == -1) {
- if (notInRevision && -1 == indexOfProperty(obj, prop->name, 0)) {
+ if (notInRevision && -1 == indexOfProperty(obj, prop->name(), 0)) {
Q_ASSERT(obj->type != -1);
const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
if (type.type) {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
} else {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name()));
}
}
@@ -1434,26 +1433,26 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
} else {
- if (prop->value || prop->values.count() != 1)
+ if (prop->value || !prop->values.isOne())
COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
prop->index = sigIdx;
obj->addSignalProperty(prop);
- if (prop->values.at(0)->object) {
- COMPILE_CHECK(buildObject(prop->values.at(0)->object, ctxt));
- prop->values.at(0)->type = Value::SignalObject;
+ if (prop->values.first()->object) {
+ COMPILE_CHECK(buildObject(prop->values.first()->object, ctxt));
+ prop->values.first()->type = Value::SignalObject;
} else {
- prop->values.at(0)->type = Value::SignalExpression;
+ prop->values.first()->type = Value::SignalExpression;
- if (!prop->values.at(0)->value.isScript())
+ if (!prop->values.first()->value.isScript())
COMPILE_EXCEPTION(prop, tr("Cannot assign a value to a signal (expecting a script to be run)"));
- QString script = prop->values.at(0)->value.asScript().trimmed();
+ QString script = prop->values.first()->value.asScript().trimmed();
if (script.isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty signal assignment"));
- compileState.signalExpressions.insert(prop->values.at(0), ctxt);
+ compileState->signalExpressions.insert(prop->values.first(), ctxt);
}
}
@@ -1467,7 +1466,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj)
{
- if(isAttachedPropertyName(prop->name) || prop->name == id_string)
+ if(isAttachedPropertyName(prop->name()) || prop->name() == id_string)
return true;
const QMetaObject *mo = obj->metaObject();
@@ -1476,7 +1475,7 @@ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
return p.name() != 0;
} else {
- int idx = indexOfProperty(obj, prop->name);
+ int idx = indexOfProperty(obj, prop->name());
return idx != -1 && mo->property(idx).isScriptable();
}
}
@@ -1485,16 +1484,16 @@ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
}
bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt)
+ QDeclarativeParser::Object *obj,
+ const BindingContext &ctxt)
{
- if (prop->isEmpty())
+ if (prop->isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty property assignment"));
const QMetaObject *metaObject = obj->metaObject();
Q_ASSERT(metaObject);
- if (isAttachedPropertyName(prop->name)) {
+ if (isAttachedPropertyName(prop->name())) {
// Setup attached property data
if (ctxt.isSubContext()) {
@@ -1506,7 +1505,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
QDeclarativeType *type = 0;
QDeclarativeImportedNamespace *typeNamespace = 0;
- unit->imports().resolveType(prop->name.toUtf8(), &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name().toUtf8(), &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
@@ -1531,19 +1530,19 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
if (p.name()) {
prop->index = p.propertyIndex();
- prop->name = QString::fromLatin1(p.name());
+ prop->setName(QString::fromLatin1(p.name()));
}
} else {
bool notInRevision = false;
- prop->index = indexOfProperty(obj, prop->name, &notInRevision);
+ prop->index = indexOfProperty(obj, prop->name(), &notInRevision);
if (prop->index == -1 && notInRevision) {
const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
if (type.type) {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
} else {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name()));
}
}
@@ -1578,17 +1577,17 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
prop->parent->setBindingBit(prop->index);
}
- if (!prop->isDefault && prop->name == id_string && !ctxt.isSubContext()) {
+ if (!prop->isDefault && prop->name() == id_string && !ctxt.isSubContext()) {
// The magic "id" behavior doesn't apply when "id" is resolved as a
// default property or to sub-objects (which are always in binding
// sub-contexts)
COMPILE_CHECK(buildIdProperty(prop, obj));
if (prop->type == QVariant::String &&
- prop->values.at(0)->value.isString())
+ prop->values.first()->value.isString())
COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
- } else if (isAttachedPropertyName(prop->name)) {
+ } else if (isAttachedPropertyName(prop->name())) {
COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt));
@@ -1597,7 +1596,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
if (prop->isDefault) {
COMPILE_EXCEPTION(prop->values.first(), tr("Cannot assign to non-existent default property"));
} else {
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name()));
}
} else if (prop->value) {
@@ -1629,15 +1628,15 @@ bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespac
if (!nsProp->value)
COMPILE_EXCEPTION(nsProp, tr("Invalid use of namespace"));
- foreach (Property *prop, nsProp->value->properties) {
+ for (Property *prop = nsProp->value->properties.first(); prop; prop = nsProp->value->properties.next(prop)) {
- if (!isAttachedPropertyName(prop->name))
+ if (!isAttachedPropertyName(prop->name()))
COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
// Setup attached property data
QDeclarativeType *type = 0;
- unit->imports().resolveType(ns, prop->name.toUtf8(), &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name().toUtf8(), &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1677,8 +1676,7 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
fetch.fetchQmlList.type = listType;
output->addInstruction(fetch);
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->type == Value::CreatedObject) {
@@ -1711,8 +1709,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
QDeclarativeParser::Object *obj,
QDeclarativeParser::Property *valueTypeProperty)
{
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->type == Value::CreatedObject ||
v->type == Value::PropertyBinding ||
@@ -1760,9 +1757,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
-
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->type == Value::ValueSource ||
v->type == Value::ValueInterceptor);
@@ -1807,19 +1802,19 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj)
{
if (prop->value ||
- prop->values.count() > 1 ||
- prop->values.at(0)->object)
+ prop->values.isMany() ||
+ prop->values.first()->object)
COMPILE_EXCEPTION(prop, tr("Invalid use of id property"));
- QDeclarativeParser::Value *idValue = prop->values.at(0);
+ QDeclarativeParser::Value *idValue = prop->values.first();
QString val = idValue->primitive();
COMPILE_CHECK(checkValidId(idValue, val));
- if (compileState.ids.contains(val))
+ if (compileState->ids.contains(val))
COMPILE_EXCEPTION(prop, tr("id is not unique"));
- prop->values.at(0)->type = Value::Id;
+ prop->values.first()->type = Value::Id;
obj->id = val;
addId(val, obj);
@@ -1829,33 +1824,35 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
void QDeclarativeCompiler::addId(const QString &id, QDeclarativeParser::Object *obj)
{
- Q_ASSERT(!compileState.ids.contains(id));
+ Q_ASSERT(!compileState->ids.contains(id));
Q_ASSERT(obj->id == id);
- obj->idIndex = compileState.ids.count();
- compileState.ids.insert(id, obj);
- compileState.idIndexes.insert(obj->idIndex, obj);
+ obj->idIndex = compileState->ids.count();
+ compileState->ids.insert(id, obj);
}
-void QDeclarativeCompiler::addBindingReference(const BindingReference &ref)
+void QDeclarativeCompiler::addBindingReference(BindingReference *ref)
{
- Q_ASSERT(ref.value && !compileState.bindings.contains(ref.value));
- compileState.bindings.insert(ref.value, ref);
+ Q_ASSERT(ref->value && !ref->value->bindingReference);
+ ref->value->bindingReference = ref;
+ compileState->bindings.prepend(ref);
}
void QDeclarativeCompiler::saveComponentState()
{
- Q_ASSERT(compileState.root);
- Q_ASSERT(!savedCompileStates.contains(compileState.root));
+ Q_ASSERT(compileState->root);
+ Q_ASSERT(compileState->root->componentCompileState == 0);
- savedCompileStates.insert(compileState.root, compileState);
- savedComponentStats.append(componentStat);
+ compileState->root->componentCompileState = compileState;
+
+ if (componentStats)
+ componentStats->savedComponentStats.append(componentStats->componentStat);
}
-QDeclarativeCompiler::ComponentCompileState
+QDeclarativeCompilerTypes::ComponentCompileState *
QDeclarativeCompiler::componentState(QDeclarativeParser::Object *obj)
{
- Q_ASSERT(savedCompileStates.contains(obj));
- return savedCompileStates.value(obj);
+ Q_ASSERT(obj->componentCompileState);
+ return obj->componentCompileState;
}
// Build attached property object. In this example,
@@ -1894,22 +1891,23 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
- if (prop->values.count()) {
- if (prop->values.at(0)->location < prop->value->location) {
+ if (!prop->values.isEmpty()) {
+ if (prop->values.first()->location < prop->value->location) {
COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
} else {
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Property has already been assigned a value"));
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Property has already been assigned a value"));
}
}
if (!obj->metaObject()->property(prop->index).isWritable()) {
- COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name()));
}
if (prop->isAlias) {
- foreach (Property *vtProp, prop->value->properties)
+ for (Property *vtProp = prop->value->properties.first(); vtProp; vtProp = prop->value->properties.next(vtProp)) {
vtProp->isAlias = true;
+ }
}
COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type],
@@ -1925,8 +1923,8 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
if (!prop->value->metatype)
COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
- if (prop->values.count())
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign a value directly to a grouped property"));
+ if (!prop->values.isEmpty())
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign a value directly to a grouped property"));
obj->addGroupedProperty(prop);
@@ -1945,13 +1943,13 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
COMPILE_EXCEPTION(obj, tr("Invalid property use"));
obj->metatype = type->metaObject();
- foreach (Property *prop, obj->properties) {
- int idx = type->metaObject()->indexOfProperty(prop->name.toUtf8().constData());
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+ int idx = type->metaObject()->indexOfProperty(prop->name().toUtf8().constData());
if (idx == -1)
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name()));
QMetaProperty p = type->metaObject()->property(idx);
if (!p.isScriptable())
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name()));
prop->index = idx;
prop->type = p.userType();
prop->isValueTypeSubProperty = true;
@@ -1959,10 +1957,10 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
if (prop->value)
COMPILE_EXCEPTION(prop, tr("Property assignment expected"));
- if (prop->values.count() > 1) {
+ if (prop->values.isMany()) {
COMPILE_EXCEPTION(prop, tr("Single property assignment expected"));
- } else if (prop->values.count()) {
- QDeclarativeParser::Value *value = prop->values.at(0);
+ } else if (!prop->values.isEmpty()) {
+ QDeclarativeParser::Value *value = prop->values.first();
if (value->object) {
COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
@@ -1975,12 +1973,12 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
if (isEnumAssignment) {
value->type = Value::Literal;
} else {
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
- reference.bindingContext.owner++;
+ BindingReference *reference = pool->New<BindingReference>();
+ reference->expression = value->value;
+ reference->property = prop;
+ reference->value = value;
+ reference->bindingContext = ctxt;
+ reference->bindingContext.owner++;
addBindingReference(reference);
value->type = Value::PropertyBinding;
}
@@ -1990,8 +1988,7 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
}
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->object);
COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, baseObj, v, ctxt));
@@ -2020,8 +2017,7 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
bool assignedBinding = false;
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(buildObject(v->object, ctxt));
@@ -2054,13 +2050,14 @@ bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeParser::Propert
QDeclarativeParser::Object *obj,
const BindingContext &ctxt)
{
- if (prop->values.count() > 1)
- COMPILE_EXCEPTION(prop->values.at(1), tr( "Cannot assign multiple values to a script property"));
+ if (prop->values.isMany())
+ COMPILE_EXCEPTION(prop->values.first()->nextValue, tr( "Cannot assign multiple values to a script property"));
- if (prop->values.at(0)->object)
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Invalid property assignment: script expected"));
+ if (prop->values.first()->object)
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Invalid property assignment: script expected"));
- obj->addScriptStringProperty(prop, ctxt.stack);
+ prop->scriptStringScope = ctxt.stack;
+ obj->addScriptStringProperty(prop);
return true;
}
@@ -2072,11 +2069,10 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
{
obj->addValueProperty(prop);
- if (prop->values.count() > 1)
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign multiple values to a singular property") );
+ if (prop->values.isMany())
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign multiple values to a singular property") );
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->object) {
COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
@@ -2088,9 +2084,7 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
}
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
-
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->object);
COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, obj, v, ctxt));
}
@@ -2108,7 +2102,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name()));
if (QDeclarativeMetaType::isInterface(prop->type)) {
@@ -2155,12 +2149,12 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
} else if (propertyMetaObject == &QDeclarativeComponent::staticMetaObject) {
// Automatic "Component" insertion
QDeclarativeParser::Object *root = v->object;
- QDeclarativeParser::Object *component = new QDeclarativeParser::Object;
+ QDeclarativeParser::Object *component = pool->New<Object>();
component->type = componentTypeRef();
component->typeName = "Qt/Component";
component->metatype = &QDeclarativeComponent::staticMetaObject;
component->location = root->location;
- QDeclarativeParser::Value *componentValue = new QDeclarativeParser::Value;
+ QDeclarativeParser::Value *componentValue = pool->New<Value>();
componentValue->object = root;
component->getDefaultProperty()->addValue(componentValue);
v->object = component;
@@ -2189,7 +2183,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name()));
// Normally buildObject() will set this up, but we need the static
@@ -2216,7 +2210,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert
buildDynamicMeta(baseObj, ForceCreation);
v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
- COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name));
+ COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name()));
}
return true;
@@ -2449,11 +2443,7 @@ bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object
if (property->value)
COMPILE_EXCEPTION(property, tr("Invalid property nesting"));
- for (int ii = 0; ii < p.defaultValue->values.count(); ++ii) {
- QDeclarativeParser::Value *v = p.defaultValue->values.at(ii);
- v->addref();
- property->values.append(v);
- }
+ property->values.append(p.defaultValue->values);
}
return true;
}
@@ -2477,7 +2467,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
newClassName.append("_QML_");
int idx = classIndexCounter()->fetchAndAddRelaxed(1);
newClassName.append(QByteArray::number(idx));
- if (compileState.root == obj && !compileState.nested) {
+ if (compileState->root == obj && !compileState->nested) {
QString path = output->url.path();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
if (lastSlash > -1) {
@@ -2676,7 +2666,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata);
if (mode == IgnoreAliases && hasAlias)
- compileState.aliasingObjects << obj;
+ compileState->aliasingObjects << obj;
obj->synthdata = dynamicData;
@@ -2749,12 +2739,12 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
if (!prop.defaultValue)
COMPILE_EXCEPTION(obj, tr("No property alias location"));
- if (prop.defaultValue->values.count() != 1 ||
- prop.defaultValue->values.at(0)->object ||
- !prop.defaultValue->values.at(0)->value.isScript())
+ if (!prop.defaultValue->values.isOne() ||
+ prop.defaultValue->values.first()->object ||
+ !prop.defaultValue->values.first()->value.isScript())
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
- QDeclarativeJS::AST::Node *node = prop.defaultValue->values.at(0)->value.asAST();
+ QDeclarativeJS::AST::Node *node = prop.defaultValue->values.first()->value.asAST();
if (!node)
COMPILE_EXCEPTION(obj, tr("No property alias location")); // ### Can this happen?
@@ -2763,10 +2753,10 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
if (alias.count() < 1 || alias.count() > 3)
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
- if (!compileState.ids.contains(alias.at(0)))
+ if (!compileState->ids.contains(alias.at(0)))
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
- QDeclarativeParser::Object *idObject = compileState.ids[alias.at(0)];
+ QDeclarativeParser::Object *idObject = compileState->ids[alias.at(0)];
QByteArray typeName;
@@ -2838,8 +2828,8 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
}
bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
- QDeclarativeParser::Property *prop,
- const BindingContext &ctxt)
+ QDeclarativeParser::Property *prop,
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
Q_ASSERT(prop->parent);
@@ -2847,13 +2837,13 @@ bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type))
- COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name));
+ COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name()));
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
+ BindingReference *reference = pool->New<BindingReference>();
+ reference->expression = value->value;
+ reference->property = prop;
+ reference->value = value;
+ reference->bindingContext = ctxt;
addBindingReference(reference);
return true;
@@ -2865,9 +2855,9 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
QDeclarativeParser::Property *valueTypeProperty)
{
Q_UNUSED(obj);
- Q_ASSERT(compileState.bindings.contains(binding));
+ Q_ASSERT(binding->bindingReference);
- const BindingReference &ref = compileState.bindings.value(binding);
+ const BindingReference &ref = *binding->bindingReference;
if (ref.dataType == BindingReference::V4) {
QDeclarativeInstruction store;
store.setType(QDeclarativeInstruction::StoreV4Binding);
@@ -2923,13 +2913,13 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
int QDeclarativeCompiler::genContextCache()
{
- if (compileState.ids.count() == 0)
+ if (compileState->ids.count() == 0)
return -1;
QDeclarativeIntegerCache *cache = new QDeclarativeIntegerCache();
- for (QHash<QString, QDeclarativeParser::Object *>::ConstIterator iter = compileState.ids.begin();
- iter != compileState.ids.end();
+ for (QHash<QString, QDeclarativeParser::Object *>::ConstIterator iter = compileState->ids.begin();
+ iter != compileState->ids.end();
++iter)
cache->add(iter.key(), (*iter)->idIndex);
@@ -2958,16 +2948,17 @@ int QDeclarativeCompiler::genPropertyData(QDeclarativeParser::Property *prop)
bool QDeclarativeCompiler::completeComponentBuild()
{
- componentStat.ids = compileState.ids.count();
+ if (componentStats)
+ componentStats->componentStat.ids = compileState->ids.count();
- for (int ii = 0; ii < compileState.aliasingObjects.count(); ++ii) {
- QDeclarativeParser::Object *aliasObject = compileState.aliasingObjects.at(ii);
+ for (int ii = 0; ii < compileState->aliasingObjects.count(); ++ii) {
+ QDeclarativeParser::Object *aliasObject = compileState->aliasingObjects.at(ii);
COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
}
QDeclarativeV4Compiler::Expression expr;
- expr.component = compileState.root;
- expr.ids = compileState.ids;
+ expr.component = compileState->root;
+ expr.ids = compileState->ids;
expr.importCache = output->importCache;
expr.imports = unit->imports();
@@ -2975,10 +2966,9 @@ bool QDeclarativeCompiler::completeComponentBuild()
QList<BindingReference*> sharedBindings;
- for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin();
- iter != compileState.bindings.end(); ++iter) {
+ for (BindingReference *b = compileState->bindings.first(); b; b = b->nextReference) {
- BindingReference &binding = *iter;
+ BindingReference &binding = *b;
// ### We don't currently optimize for bindings on alias's - because
// of the solution to QTBUG-13719
@@ -2991,7 +2981,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
if (index != -1) {
binding.dataType = BindingReference::V4;
binding.compiledIndex = index;
- componentStat.optimizedBindings.append(iter.key()->location);
+ if (componentStats)
+ componentStats->componentStat.optimizedBindings.append(b->value->location);
continue;
}
}
@@ -3000,19 +2991,20 @@ bool QDeclarativeCompiler::completeComponentBuild()
QString expression = binding.expression.asScript();
QDeclarativeRewrite::RewriteBinding rewriteBinding;
- rewriteBinding.setName(QLatin1Char('$')+binding.property->name);
+ rewriteBinding.setName(QLatin1Char('$')+binding.property->name());
bool isSharable = false;
binding.rewrittenExpression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
if (isSharable && !binding.property->isAlias /* See above re alias */ &&
binding.property->type != qMetaTypeId<QDeclarativeBinding*>()) {
binding.dataType = BindingReference::V8;
- sharedBindings.append(&iter.value());
+ sharedBindings.append(b);
} else {
binding.dataType = BindingReference::QtScript;
}
- componentStat.scriptBindings.append(iter.key()->location);
+ if (componentStats)
+ componentStats->componentStat.scriptBindings.append(b->value->location);
}
if (!sharedBindings.isEmpty()) {
@@ -3046,14 +3038,14 @@ bool QDeclarativeCompiler::completeComponentBuild()
}
functionArray += QLatin1String("]");
- compileState.v8BindingProgram = functionArray;
- compileState.v8BindingProgramLine = startLineNumber;
- compileState.v8BindingProgramIndex = output->v8bindings.count();
+ compileState->v8BindingProgram = functionArray;
+ compileState->v8BindingProgramLine = startLineNumber;
+ compileState->v8BindingProgramIndex = output->v8bindings.count();
output->v8bindings.append(v8::Persistent<v8::Array>());
}
if (bindingCompiler.isValid())
- compileState.compiledBindingData = bindingCompiler.program();
+ compileState->compiledBindingData = bindingCompiler.program();
saveComponentState();
@@ -3062,9 +3054,10 @@ bool QDeclarativeCompiler::completeComponentBuild()
void QDeclarativeCompiler::dumpStats()
{
+ Q_ASSERT(componentStats);
qWarning().nospace() << "QML Document: " << output->url.toString();
- for (int ii = 0; ii < savedComponentStats.count(); ++ii) {
- const ComponentStat &stat = savedComponentStats.at(ii);
+ for (int ii = 0; ii < componentStats->savedComponentStats.count(); ++ii) {
+ const ComponentStat &stat = componentStats->savedComponentStats.at(ii);
qWarning().nospace() << " Component Line " << stat.lineNumber;
qWarning().nospace() << " Total Objects: " << stat.objects;
qWarning().nospace() << " IDs Used: " << stat.ids;
@@ -3210,24 +3203,25 @@ int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, co
{
if (notInRevision) *notInRevision = false;
- if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
- QDeclarativePropertyCache *cache =
- object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
+ QDeclarativePropertyCache *cache = 0;
- QDeclarativePropertyCache::Data *d = cache->property(name);
- // Find the first property
- while (d && d->isFunction())
- d = cache->overrideData(d);
+ if (object->synthCache)
+ cache = object->synthCache;
+ else if (object->type != -1)
+ cache = output->types[object->type].createPropertyCache(engine);
+ else
+ cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- if (d && !cache->isAllowedInRevision(d)) {
- if (notInRevision) *notInRevision = true;
- return -1;
- } else {
- return d?d->coreIndex:-1;
- }
+ QDeclarativePropertyCache::Data *d = cache->property(name);
+ // Find the first property
+ while (d && d->isFunction())
+ d = cache->overrideData(d);
+
+ if (d && !cache->isAllowedInRevision(d)) {
+ if (notInRevision) *notInRevision = true;
+ return -1;
} else {
- const QMetaObject *mo = object->metaObject();
- return mo->indexOfProperty(name.toUtf8().constData());
+ return d?d->coreIndex:-1;
}
}
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 771a81eb74..7014ce2af7 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -139,12 +139,89 @@ private:
int indexForUrl(const QUrl &);
};
+namespace QDeclarativeCompilerTypes {
+ struct BindingContext
+ {
+ BindingContext()
+ : stack(0), owner(0), object(0) {}
+ BindingContext(QDeclarativeParser::Object *o)
+ : stack(0), owner(0), object(o) {}
+ BindingContext incr() const {
+ BindingContext rv(object);
+ rv.stack = stack + 1;
+ return rv;
+ }
+ bool isSubContext() const { return stack != 0; }
+ int stack;
+ int owner;
+ QDeclarativeParser::Object *object;
+ };
+
+ struct BindingReference : public QDeclarativePool::Class
+ {
+ BindingReference() : nextReference(0) {}
+
+ QDeclarativeParser::Variant expression;
+ QDeclarativeParser::Property *property;
+ QDeclarativeParser::Value *value;
+
+ enum DataType { QtScript, V4, V8 };
+ DataType dataType;
+
+ int compiledIndex;
+
+ QString rewrittenExpression;
+ BindingContext bindingContext;
+
+ BindingReference *nextReference;
+ };
+
+ // Contains all the incremental compiler state about a component. As
+ // a single QML file can have multiple components defined, there may be
+ // more than one of these for each compile
+ struct ComponentCompileState : public QDeclarativePool::Class
+ {
+ ComponentCompileState()
+ : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
+ QHash<QString, QDeclarativeParser::Object *> ids;
+ int parserStatusCount;
+ int pushedProperties;
+ bool nested;
+
+ QByteArray compiledBindingData;
+ QString v8BindingProgram;
+ int v8BindingProgramLine;
+ int v8BindingProgramIndex;
+
+ struct BindingReferenceList {
+ BindingReferenceList() : _count(0), _first(0) {}
+ QDeclarativeCompilerTypes::BindingReference *first() const { return _first; }
+ void prepend(QDeclarativeCompilerTypes::BindingReference *ref) {
+ Q_ASSERT(ref);
+ Q_ASSERT(0 == ref->nextReference);
+ ref->nextReference = _first;
+ _first = ref;
+ ++_count;
+ }
+ int count() const { return _count; }
+ private:
+ int _count;
+ QDeclarativeCompilerTypes::BindingReference *_first;
+ };
+
+ BindingReferenceList bindings;
+ QHash<QDeclarativeParser::Value *, QDeclarativeCompilerTypes::BindingContext> signalExpressions;
+ QList<QDeclarativeParser::Object *> aliasingObjects;
+ QDeclarativeParser::Object *root;
+ };
+};
+
class QMetaObjectBuilder;
class Q_AUTOTEST_EXPORT QDeclarativeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
public:
- QDeclarativeCompiler();
+ QDeclarativeCompiler(QDeclarativePool *);
bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
@@ -161,69 +238,53 @@ public:
private:
static void reset(QDeclarativeCompiledData *);
- struct BindingContext {
- BindingContext()
- : stack(0), owner(0), object(0) {}
- BindingContext(QDeclarativeParser::Object *o)
- : stack(0), owner(0), object(o) {}
- BindingContext incr() const {
- BindingContext rv(object);
- rv.stack = stack + 1;
- return rv;
- }
- bool isSubContext() const { return stack != 0; }
- int stack;
- int owner;
- QDeclarativeParser::Object *object;
- };
-
void compileTree(QDeclarativeParser::Object *tree);
- bool buildObject(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildComponent(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &);
+ bool buildObject(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildComponent(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildSubObject(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
- const BindingContext &);
+ const QDeclarativeCompilerTypes::BindingContext &);
bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
- const BindingContext &);
+ const QDeclarativeCompilerTypes::BindingContext &);
bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &);
+ const QDeclarativeCompilerTypes::BindingContext &);
bool buildIdProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
bool buildAttachedProperty(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildGroupedProperty(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildValueTypeProperty(QObject *type,
QDeclarativeParser::Object *obj,
QDeclarativeParser::Object *baseObj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildListProperty(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildScriptStringProperty(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildPropertyAssignment(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
QDeclarativeParser::Object *baseObj,
QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj,
QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool doesPropertyExist(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
bool testLiteralAssignment(const QMetaProperty &prop,
QDeclarativeParser::Value *value);
@@ -236,8 +297,8 @@ private:
bool buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode);
bool checkDynamicMeta(QDeclarativeParser::Object *obj);
bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop,
- const BindingContext &ctxt);
- bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const BindingContext &);
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
bool compileAlias(QMetaObjectBuilder &,
QByteArray &data,
QDeclarativeParser::Object *obj,
@@ -281,43 +342,24 @@ private:
void dumpStats();
- struct BindingReference {
- QDeclarativeParser::Variant expression;
- QDeclarativeParser::Property *property;
- QDeclarativeParser::Value *value;
+ void addBindingReference(QDeclarativeCompilerTypes::BindingReference *);
- enum DataType { QtScript, V4, V8 };
- DataType dataType;
+ QDeclarativeCompilerTypes::ComponentCompileState *compileState;
- int compiledIndex;
+ QDeclarativePool *pool;
- QString rewrittenExpression;
- BindingContext bindingContext;
- };
- void addBindingReference(const BindingReference &);
-
- struct ComponentCompileState
- {
- ComponentCompileState()
- : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
- QHash<QString, QDeclarativeParser::Object *> ids;
- QHash<int, QDeclarativeParser::Object *> idIndexes;
- int parserStatusCount;
- int pushedProperties;
- bool nested;
+ QDeclarativeCompilerTypes::ComponentCompileState *componentState(QDeclarativeParser::Object *);
+ void saveComponentState();
- QByteArray compiledBindingData;
- QString v8BindingProgram;
- int v8BindingProgramLine;
- int v8BindingProgramIndex;
+ QList<QDeclarativeError> exceptions;
+ QDeclarativeCompiledData *output;
+ QDeclarativeEngine *engine;
+ QDeclarativeEnginePrivate *enginePrivate;
+ QDeclarativeParser::Object *unitRoot;
+ QDeclarativeTypeData *unit;
- QHash<QDeclarativeParser::Value *, BindingReference> bindings;
- QHash<QDeclarativeParser::Value *, BindingContext> signalExpressions;
- QList<QDeclarativeParser::Object *> aliasingObjects;
- QDeclarativeParser::Object *root;
- };
- ComponentCompileState compileState;
+ // Compiler component statistics. Only collected if QML_COMPILER_STATS=1
struct ComponentStat
{
ComponentStat() : ids(0), objects(0) {}
@@ -329,21 +371,14 @@ private:
QList<QDeclarativeParser::LocationSpan> optimizedBindings;
int objects;
};
- ComponentStat componentStat;
-
- void saveComponentState();
-
- ComponentCompileState componentState(QDeclarativeParser::Object *);
- QHash<QDeclarativeParser::Object *, ComponentCompileState> savedCompileStates;
- QList<ComponentStat> savedComponentStats;
-
- QList<QDeclarativeError> exceptions;
- QDeclarativeCompiledData *output;
- QDeclarativeEngine *engine;
- QDeclarativeEnginePrivate *enginePrivate;
- QDeclarativeParser::Object *unitRoot;
- QDeclarativeTypeData *unit;
+ struct ComponentStats : public QDeclarativePool::Class
+ {
+ ComponentStat componentStat;
+ QList<ComponentStat> savedComponentStats;
+ };
+ ComponentStats *componentStats;
};
+
QT_END_NAMESPACE
#endif // QDECLARATIVECOMPILER_P_H
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index ed899148bc..52c4f2d2ae 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -101,12 +101,7 @@ QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root
rootNode.d->name = root->typeName;
rootNode.d->location = root->location.start;
- for(QHash<QString, Property *>::Iterator iter = root->properties.begin();
- iter != root->properties.end();
- ++iter) {
-
- Property *p = *iter;
-
+ for (Property *p = root->properties.first(); p; p = root->properties.next(p)) {
rootNode.d->properties << fromProperty(p);
}
@@ -120,8 +115,8 @@ QDeclarativeCustomParserProperty
QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
{
QDeclarativeCustomParserProperty prop;
- prop.d->name = p->name.toUtf8();
- prop.d->isList = (p->values.count() > 1);
+ prop.d->name = p->name().toUtf8();
+ prop.d->isList = p->values.isMany();
prop.d->location = p->location.start;
if (p->value) {
@@ -130,8 +125,7 @@ QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *
for (int ii = 0; ii < props.count(); ++ii)
prop.d->values << QVariant::fromValue(props.at(ii));
} else {
- for(int ii = 0; ii < p->values.count(); ++ii) {
- QDeclarativeParser::Value *v = p->values.at(ii);
+ for (QDeclarativeParser::Value *v = p->values.first(); v; v = p->values.next(v)) {
v->type = QDeclarativeParser::Value::Literal;
if(v->object) {
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
index d8dd72933d..bba26215cb 100644
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ b/src/declarative/qml/qdeclarativeparser.cpp
@@ -66,31 +66,14 @@ using namespace QDeclarativeJS;
using namespace QDeclarativeParser;
QDeclarativeParser::Object::Object()
-: type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1)
+: type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1),
+ componentCompileState(0)
{
}
QDeclarativeParser::Object::~Object()
{
- if (defaultProperty) defaultProperty->release();
if (synthCache) synthCache->release();
- foreach(Property *prop, properties)
- prop->release();
- foreach(Property *prop, valueProperties)
- prop->release();
- foreach(Property *prop, signalProperties)
- prop->release();
- foreach(Property *prop, attachedProperties)
- prop->release();
- foreach(Property *prop, groupedProperties)
- prop->release();
- foreach(Property *prop, valueTypeProperties)
- prop->release();
- typedef QPair<Property *, int> PropPair;
- foreach(const PropPair &prop, scriptStringProperties)
- prop.first->release();
- foreach(const DynamicProperty &prop, dynamicProperties)
- if (prop.defaultValue) prop.defaultValue->release();
}
void Object::setBindingBit(int b)
@@ -113,7 +96,7 @@ const QMetaObject *Object::metaObject() const
QDeclarativeParser::Property *Object::getDefaultProperty()
{
if (!defaultProperty) {
- defaultProperty = new Property;
+ defaultProperty = pool()->New<Property>();
defaultProperty->parent = this;
}
return defaultProperty;
@@ -121,53 +104,70 @@ QDeclarativeParser::Property *Object::getDefaultProperty()
void QDeclarativeParser::Object::addValueProperty(Property *p)
{
- p->addref();
- valueProperties << p;
+ valueProperties.append(p);
}
void QDeclarativeParser::Object::addSignalProperty(Property *p)
{
- p->addref();
- signalProperties << p;
+ signalProperties.append(p);
}
void QDeclarativeParser::Object::addAttachedProperty(Property *p)
{
- p->addref();
- attachedProperties << p;
+ attachedProperties.append(p);
}
void QDeclarativeParser::Object::addGroupedProperty(Property *p)
{
- p->addref();
- groupedProperties << p;
+ groupedProperties.append(p);
}
void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
{
- p->addref();
- valueTypeProperties << p;
+ valueTypeProperties.append(p);
}
-void QDeclarativeParser::Object::addScriptStringProperty(Property *p, int stack)
+void QDeclarativeParser::Object::addScriptStringProperty(Property *p)
{
- p->addref();
- scriptStringProperties << qMakePair(p, stack);
+ scriptStringProperties.append(p);
}
+Property *QDeclarativeParser::Object::getProperty(const QString *name, bool create)
+{
+ for (Property *p = properties.first(); p; p = properties.next(p)) {
+ if (p->name() == *name)
+ return p;
+ }
+
+ if (create) {
+ Property *property = pool()->New<Property>();
+ property->parent = this;
+ property->_name = const_cast<QString *>(name);
+ property->isDefault = false;
+ properties.prepend(property);
+ return property;
+ } else {
+ return 0;
+ }
+}
Property *QDeclarativeParser::Object::getProperty(const QString &name, bool create)
{
- if (!properties.contains(name)) {
- if (create) {
- Property *property = new Property(name);
- property->parent = this;
- properties.insert(name, property);
- } else {
- return 0;
- }
+ for (Property *p = properties.first(); p; p = properties.next(p)) {
+ if (p->name() == name)
+ return p;
+ }
+
+ if (create) {
+ Property *property = pool()->New<Property>();
+ property->parent = this;
+ property->_name = pool()->NewString(name);
+ property->isDefault = false;
+ properties.prepend(property);
+ return property;
+ } else {
+ return 0;
}
- return properties[name];
}
QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
@@ -205,40 +205,26 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
}
QDeclarativeParser::Property::Property()
-: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
- isValueTypeSubProperty(false), isAlias(false)
-{
-}
-
-QDeclarativeParser::Property::Property(const QString &n)
-: parent(0), type(0), index(-1), value(0), name(n), isDefault(false),
- isDeferred(false), isValueTypeSubProperty(false), isAlias(false)
+: parent(0), type(0), index(-1), value(0), _name(0), isDefault(true), isDeferred(false),
+ isValueTypeSubProperty(false), isAlias(false), scriptStringScope(-1), nextProperty(0),
+ nextMainProperty(0)
{
}
-QDeclarativeParser::Property::~Property()
-{
- foreach(Value *value, values)
- value->release();
- foreach(Value *value, onValues)
- value->release();
- if (value) value->release();
-}
-
QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
{
- if (!value) { value = new QDeclarativeParser::Object; value->location = l; }
+ if (!value) { value = pool()->New<Object>(); value->location = l; }
return value;
}
void QDeclarativeParser::Property::addValue(Value *v)
{
- values << v;
+ values.append(v);
}
void QDeclarativeParser::Property::addOnValue(Value *v)
{
- onValues << v;
+ onValues.append(v);
}
bool QDeclarativeParser::Property::isEmpty() const
@@ -247,20 +233,17 @@ bool QDeclarativeParser::Property::isEmpty() const
}
QDeclarativeParser::Value::Value()
-: type(Unknown), object(0)
+: type(Unknown), object(0), bindingReference(0), nextValue(0)
{
}
-QDeclarativeParser::Value::~Value()
-{
- if (object) object->release();
-}
-
QDeclarativeParser::Variant::Variant()
-: t(Invalid) {}
+: t(Invalid)
+{
+}
QDeclarativeParser::Variant::Variant(const Variant &o)
-: t(o.t), d(o.d), s(o.s)
+: t(o.t), d(o.d), asWritten(o.asWritten)
{
}
@@ -269,18 +252,18 @@ QDeclarativeParser::Variant::Variant(bool v)
{
}
-QDeclarativeParser::Variant::Variant(double v, const QString &asWritten)
-: t(Number), d(v), s(asWritten)
+QDeclarativeParser::Variant::Variant(double v, const QStringRef &asWritten)
+: t(Number), d(v), asWritten(asWritten)
{
}
-QDeclarativeParser::Variant::Variant(const QString &v)
-: t(String), s(v)
+QDeclarativeParser::Variant::Variant(QDeclarativeJS::AST::StringLiteral *v)
+: t(String), l(v)
{
}
-QDeclarativeParser::Variant::Variant(const QString &v, QDeclarativeJS::AST::Node *n)
-: t(Script), n(n), s(v)
+QDeclarativeParser::Variant::Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *n)
+: t(Script), n(n), asWritten(asWritten)
{
}
@@ -288,7 +271,7 @@ QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Varian
{
t = o.t;
d = o.d;
- s = o.s;
+ asWritten = o.asWritten;
return *this;
}
@@ -304,7 +287,11 @@ bool QDeclarativeParser::Variant::asBoolean() const
QString QDeclarativeParser::Variant::asString() const
{
- return s;
+ if (t == String) {
+ return l->value->asString();
+ } else {
+ return asWritten.toString();
+ }
}
double QDeclarativeParser::Variant::asNumber() const
@@ -364,14 +351,17 @@ QString QDeclarativeParser::Variant::asScript() const
case Boolean:
return b?QLatin1String("true"):QLatin1String("false");
case Number:
- if (s.isEmpty())
+ if (asWritten.isEmpty())
return QString::number(d);
- else
- return s;
+ else
+ return asWritten.toString();
case String:
- return escapedString(s);
+ return escapedString(asString());
case Script:
- return s;
+ if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(n))
+ return i->name->asString();
+ else
+ return asWritten.toString();
}
}
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 6a200554e7..496041bd29 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -64,6 +64,8 @@
#include <private/qobject_p.h>
#include <private/qdeclarativerefcount_p.h>
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativepool_p.h>
+#include <private/qfieldlist_p.h>
QT_BEGIN_HEADER
@@ -72,7 +74,8 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativePropertyCache;
-namespace QDeclarativeJS { namespace AST { class Node; } }
+namespace QDeclarativeJS { namespace AST { class Node; class StringLiteral; } }
+namespace QDeclarativeCompilerTypes { class BindingReference; class ComponentCompileState; }
/*
XXX
@@ -92,6 +95,11 @@ namespace QDeclarativeParser
Location() : line(-1), column(-1) {}
int line;
int column;
+
+ inline bool operator<(const Location &other) {
+ return line < other.line ||
+ (line == other.line && column < other.column);
+ }
};
struct LocationRange
@@ -113,123 +121,8 @@ namespace QDeclarativeParser
}
};
+ class Object;
class Property;
- class Object : public QDeclarativeRefCount
- {
- public:
- Object();
- virtual ~Object();
-
- // Type of the object. The integer is an index into the
- // QDeclarativeCompiledData::types array, or -1 if the object is a property
- // group.
- int type;
-
- // The fully-qualified name of this type
- QByteArray typeName;
- // The id assigned to the object (if any). Set by the QDeclarativeCompiler
- QString id;
- // The id index assigned to the object (if any). Set by the QDeclarativeCompiler
- int idIndex;
- // Custom parsed data
- QByteArray custom;
- // Bit mask of the properties assigned bindings
- QByteArray bindingBitmask;
- void setBindingBit(int);
- // Returns the metaobject for this type, or 0 if not available.
- // Internally selectd between the metatype and extObject variables
- const QMetaObject *metaObject() const;
-
- // The compile time metaobject for this type
- const QMetaObject *metatype;
- // The synthesized metaobject, if QML added signals or properties to
- // this type. Otherwise null
- QAbstractDynamicMetaObject extObject;
- QByteArray metadata; // Generated by compiler
- QByteArray synthdata; // Generated by compiler
- QDeclarativePropertyCache *synthCache; // Generated by compiler
-
- Property *getDefaultProperty();
- Property *getProperty(const QString &name, bool create=true);
-
- Property *defaultProperty;
- QHash<QString, Property *> properties;
-
- // Output of the compilation phase (these properties continue to exist
- // in either the defaultProperty or properties members too)
- void addValueProperty(Property *);
- void addSignalProperty(Property *);
- void addAttachedProperty(Property *);
- void addGroupedProperty(Property *);
- void addValueTypeProperty(Property *);
- void addScriptStringProperty(Property *, int = 0);
- QList<Property *> valueProperties;
- QList<Property *> signalProperties;
- QList<Property *> attachedProperties;
- QList<Property *> groupedProperties;
- QList<Property *> valueTypeProperties;
- QList<QPair<Property *, int> > scriptStringProperties;
-
- // Script blocks that were nested under this object
- struct ScriptBlock {
- enum Pragma {
- None = 0x00000000,
- Shared = 0x00000001
- };
- Q_DECLARE_FLAGS(Pragmas, Pragma)
-
- QString code;
- QString file;
- Pragmas pragmas;
- };
-
- // The bytes to cast instances by to get to the QDeclarativeParserStatus
- // interface. -1 indicates the type doesn't support this interface.
- // Set by the QDeclarativeCompiler.
- int parserStatusCast;
-
- LocationSpan location;
-
- struct DynamicProperty {
- DynamicProperty();
- DynamicProperty(const DynamicProperty &);
-
- enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList };
-
- bool isDefaultProperty;
- Type type;
- QByteArray customType;
- QByteArray name;
- QDeclarativeParser::Property *defaultValue;
- LocationSpan location;
- };
- struct DynamicSignal {
- DynamicSignal();
- DynamicSignal(const DynamicSignal &);
-
- QByteArray name;
- QList<QByteArray> parameterTypes;
- QList<QByteArray> parameterNames;
- LocationSpan location;
- };
- struct DynamicSlot {
- DynamicSlot();
- DynamicSlot(const DynamicSlot &);
-
- QByteArray name;
- QString body;
- QList<QByteArray> parameterNames;
- LocationSpan location;
- };
-
- // The list of dynamic properties
- QList<DynamicProperty> dynamicProperties;
- // The list of dynamic signals
- QList<DynamicSignal> dynamicSignals;
- // The list of dynamic slots
- QList<DynamicSlot> dynamicSlots;
- };
-
class Q_DECLARATIVE_EXPORT Variant
{
public:
@@ -243,10 +136,10 @@ namespace QDeclarativeParser
Variant();
Variant(const Variant &);
- Variant(bool);
- Variant(double, const QString &asWritten=QString());
- Variant(const QString &);
- Variant(const QString &, QDeclarativeJS::AST::Node *);
+ explicit Variant(bool);
+ explicit Variant(double, const QStringRef &asWritten = QStringRef());
+ explicit Variant(QDeclarativeJS::AST::StringLiteral *);
+ explicit Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *);
Variant &operator=(const Variant &);
Type type() const;
@@ -269,16 +162,16 @@ namespace QDeclarativeParser
union {
bool b;
double d;
+ QDeclarativeJS::AST::StringLiteral *l;
QDeclarativeJS::AST::Node *n;
};
- QString s;
+ QStringRef asWritten;
};
- class Value : public QDeclarativeRefCount
+ class Value : public QDeclarativePool::POD
{
public:
Value();
- virtual ~Value();
enum Type {
// The type of this value assignment is not yet known
@@ -311,14 +204,18 @@ namespace QDeclarativeParser
Object *object;
LocationSpan location;
+
+ // Used by compiler
+ QDeclarativeCompilerTypes::BindingReference *bindingReference;
+
+ // Used in Property::ValueList lists
+ Value *nextValue;
};
- class Property : public QDeclarativeRefCount
+ class Property : public QDeclarativePool::POD
{
public:
Property();
- Property(const QString &n);
- virtual ~Property();
// The Object to which this property is attached
Object *parent;
@@ -336,16 +233,19 @@ namespace QDeclarativeParser
// Returns true if this is an empty property - both value and values
// are unset.
bool isEmpty() const;
+
+ typedef QFieldList<Value, &Value::nextValue> ValueList;
// The list of values assigned to this property. Content in values
// and value are mutually exclusive
- QList<Value *> values;
+ ValueList values;
// The list of values assigned to this property using the "on" syntax
- QList<Value *> onValues;
+ ValueList onValues;
// The accessed property. This is used to represent dot properties.
// Content in value and values are mutually exclusive.
Object *value;
// The property name
- QString name;
+ QString name() const { return _name?*_name:QString(); }
+ void setName(const QString &n) { _name = pool()->NewString(n); }
// True if this property was accessed as the default property.
bool isDefault;
// True if the setting of this property will be deferred. Set by the
@@ -357,9 +257,147 @@ namespace QDeclarativeParser
// QDeclarativeCompiler
bool isAlias;
+ // Used for scriptStringProperties
+ int scriptStringScope;
+
LocationSpan location;
LocationRange listValueRange;
+
+ // Used in Object::MainPropertyList
+ Property *nextMainProperty;
+
+ // Used in Object::PropertyList lists
+ Property *nextProperty;
+
+ private:
+ friend class Object;
+ QString *_name;
};
+
+ class Object : public QDeclarativePool::Class
+ {
+ public:
+ Object();
+ virtual ~Object();
+
+ // Type of the object. The integer is an index into the
+ // QDeclarativeCompiledData::types array, or -1 if the object is a property
+ // group.
+ int type;
+
+ // The fully-qualified name of this type
+ QByteArray typeName;
+ // The id assigned to the object (if any). Set by the QDeclarativeCompiler
+ QString id;
+ // The id index assigned to the object (if any). Set by the QDeclarativeCompiler
+ int idIndex;
+ // Custom parsed data
+ QByteArray custom;
+ // Bit mask of the properties assigned bindings
+ QByteArray bindingBitmask;
+ void setBindingBit(int);
+ // Returns the metaobject for this type, or 0 if not available.
+ // Internally selectd between the metatype and extObject variables
+ const QMetaObject *metaObject() const;
+
+ // The compile time metaobject for this type
+ const QMetaObject *metatype;
+ // The synthesized metaobject, if QML added signals or properties to
+ // this type. Otherwise null
+ QAbstractDynamicMetaObject extObject;
+ QByteArray metadata; // Generated by compiler
+ QByteArray synthdata; // Generated by compiler
+ QDeclarativePropertyCache *synthCache; // Generated by compiler
+
+ Property *getDefaultProperty();
+ // name ptr must be guarenteed to remain valid
+ Property *getProperty(const QString *name, bool create=true);
+ Property *getProperty(const QString &name, bool create=true);
+
+ Property *defaultProperty;
+
+ typedef QFieldList<Property, &Property::nextMainProperty> MainPropertyList;
+ MainPropertyList properties;
+
+ // Output of the compilation phase (these properties continue to exist
+ // in either the defaultProperty or properties members too)
+ void addValueProperty(Property *);
+ void addSignalProperty(Property *);
+ void addAttachedProperty(Property *);
+ void addGroupedProperty(Property *);
+ void addValueTypeProperty(Property *);
+ void addScriptStringProperty(Property *);
+
+ typedef QFieldList<Property, &Property::nextProperty> PropertyList;
+ PropertyList valueProperties;
+ PropertyList signalProperties;
+ PropertyList attachedProperties;
+ PropertyList groupedProperties;
+ PropertyList valueTypeProperties;
+ PropertyList scriptStringProperties;
+
+ // Script blocks that were nested under this object
+ struct ScriptBlock {
+ enum Pragma {
+ None = 0x00000000,
+ Shared = 0x00000001
+ };
+ Q_DECLARE_FLAGS(Pragmas, Pragma)
+
+ QString code;
+ QString file;
+ Pragmas pragmas;
+ };
+
+ // The bytes to cast instances by to get to the QDeclarativeParserStatus
+ // interface. -1 indicates the type doesn't support this interface.
+ // Set by the QDeclarativeCompiler.
+ int parserStatusCast;
+
+ LocationSpan location;
+
+ struct DynamicProperty {
+ DynamicProperty();
+ DynamicProperty(const DynamicProperty &);
+
+ enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList };
+
+ bool isDefaultProperty;
+ Type type;
+ QByteArray customType;
+ QByteArray name;
+ QDeclarativeParser::Property *defaultValue;
+ LocationSpan location;
+ };
+ struct DynamicSignal {
+ DynamicSignal();
+ DynamicSignal(const DynamicSignal &);
+
+ QByteArray name;
+ QList<QByteArray> parameterTypes;
+ QList<QByteArray> parameterNames;
+ };
+ struct DynamicSlot {
+ DynamicSlot();
+ DynamicSlot(const DynamicSlot &);
+
+ QByteArray name;
+ QString body;
+ QList<QByteArray> parameterNames;
+ LocationSpan location;
+ };
+
+ // The list of dynamic properties
+ QList<DynamicProperty> dynamicProperties;
+ // The list of dynamic signals
+ QList<DynamicSignal> dynamicSignals;
+ // The list of dynamic slots
+ QList<DynamicSlot> dynamicSlots;
+
+ // Used by compiler
+ QDeclarativeCompilerTypes::ComponentCompileState *componentCompileState;
+ };
+
}
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas);
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index dcd12e287a..b5415114fd 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -100,12 +100,27 @@ class ProcessAST: protected AST::Visitor
const State &state = top();
if (state.property) {
State s(state.property->getValue(location),
- state.property->getValue(location)->getProperty(name.toUtf8()));
+ state.property->getValue(location)->getProperty(name));
s.property->location = location;
push(s);
} else {
- State s(state.object,
- state.object->getProperty(name.toUtf8()));
+ State s(state.object, state.object->getProperty(name));
+
+ s.property->location = location;
+ push(s);
+ }
+ }
+
+ void pushProperty(const QString *name, const LocationSpan &location)
+ {
+ const State &state = top();
+ if (state.property) {
+ State s(state.property->getValue(location),
+ state.property->getValue(location)->getProperty(name));
+ s.property->location = location;
+ push(s);
+ } else {
+ State s(state.object, state.object->getProperty(name));
s.property->location = location;
push(s);
@@ -157,12 +172,18 @@ protected:
QString qualifiedNameId() const;
QString textAt(const AST::SourceLocation &loc) const
- { return _contents.mid(loc.offset, loc.length); }
+ { return _contents->mid(loc.offset, loc.length); }
+ QStringRef textRefAt(const AST::SourceLocation &loc) const
+ { return QStringRef(_contents, loc.offset, loc.length); }
QString textAt(const AST::SourceLocation &first,
const AST::SourceLocation &last) const
- { return _contents.mid(first.offset, last.offset + last.length - first.offset); }
+ { return _contents->mid(first.offset, last.offset + last.length - first.offset); }
+
+ QStringRef textRefAt(const AST::SourceLocation &first,
+ const AST::SourceLocation &last) const
+ { return QStringRef(_contents, first.offset, last.offset + last.length - first.offset); }
QString asString(AST::ExpressionNode *expr)
{
@@ -172,6 +193,14 @@ protected:
return textAt(expr->firstSourceLocation(), expr->lastSourceLocation());
}
+ QStringRef asStringRef(AST::ExpressionNode *expr)
+ {
+ if (! expr)
+ return QStringRef();
+
+ return textRefAt(expr->firstSourceLocation(), expr->lastSourceLocation());
+ }
+
QString asString(AST::Statement *stmt)
{
if (! stmt)
@@ -182,11 +211,19 @@ protected:
return s;
}
+ QStringRef asStringRef(AST::Statement *stmt)
+ {
+ if (! stmt)
+ return QStringRef();
+
+ return textRefAt(stmt->firstSourceLocation(), stmt->lastSourceLocation());
+ }
+
private:
QDeclarativeScriptParser *_parser;
StateStack _stateStack;
QStringList _scope;
- QString _contents;
+ const QString *_contents;
};
ProcessAST::ProcessAST(QDeclarativeScriptParser *parser)
@@ -200,7 +237,7 @@ ProcessAST::~ProcessAST()
void ProcessAST::operator()(const QString &code, AST::Node *node)
{
- _contents = code;
+ _contents = &code;
accept(node);
}
@@ -262,11 +299,11 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
int propertyCount = 0;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(&name->name->asString(),
this->location(name));
}
- if (!onAssignment && propertyCount && currentProperty() && currentProperty()->values.count()) {
+ if (!onAssignment && propertyCount && currentProperty() && !currentProperty()->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -303,7 +340,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
if (lastTypeDot >= 0)
resolvableObjectType.replace(QLatin1Char('.'),QLatin1Char('/'));
- QDeclarativeParser::Object *obj = new QDeclarativeParser::Object;
+ QDeclarativeParser::Object *obj = _parser->_pool.New<QDeclarativeParser::Object>();
QDeclarativeScriptParser::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
obj->type = typeRef->id;
@@ -319,7 +356,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
if (propertyCount) {
Property *prop = currentProperty();
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeParser::Value *v = _parser->_pool.New<QDeclarativeParser::Value>();
v->object = obj;
v->location = obj->location;
if (onAssignment)
@@ -336,7 +373,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
_parser->setTree(obj);
} else {
const State state = _stateStack.top();
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeParser::Value *v = _parser->_pool.New<QDeclarativeParser::Value>();
v->object = obj;
v->location = obj->location;
if (state.property) {
@@ -607,16 +644,16 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
node->lastSourceLocation());
if (node->statement) { // default value
- property.defaultValue = new Property;
+ property.defaultValue = _parser->_pool.New<Property>();
property.defaultValue->parent = _stateStack.top().object;
property.defaultValue->location =
location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
- QDeclarativeParser::Value *value = new QDeclarativeParser::Value;
+ QDeclarativeParser::Value *value = _parser->_pool.New<QDeclarativeParser::Value>();
value->location = location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
value->value = getVariant(node->statement);
- property.defaultValue->values << value;
+ property.defaultValue->values.append(value);
}
_stateStack.top().object->dynamicProperties << property;
@@ -666,7 +703,7 @@ QDeclarativeParser::Variant ProcessAST::getVariant(AST::Statement *stmt)
if (AST::ExpressionStatement *exprStmt = AST::cast<AST::ExpressionStatement *>(stmt))
return getVariant(exprStmt->expression);
- return QDeclarativeParser::Variant(asString(stmt), stmt);
+ return QDeclarativeParser::Variant(asStringRef(stmt), stmt);
}
return QDeclarativeParser::Variant();
@@ -675,22 +712,22 @@ QDeclarativeParser::Variant ProcessAST::getVariant(AST::Statement *stmt)
QDeclarativeParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
{
if (AST::StringLiteral *lit = AST::cast<AST::StringLiteral *>(expr)) {
- return QDeclarativeParser::Variant(lit->value->asString());
+ return QDeclarativeParser::Variant(lit);
} else if (expr->kind == AST::Node::Kind_TrueLiteral) {
return QDeclarativeParser::Variant(true);
} else if (expr->kind == AST::Node::Kind_FalseLiteral) {
return QDeclarativeParser::Variant(false);
} else if (AST::NumericLiteral *lit = AST::cast<AST::NumericLiteral *>(expr)) {
- return QDeclarativeParser::Variant(lit->value, asString(expr));
+ return QDeclarativeParser::Variant(lit->value, asStringRef(expr));
} else {
if (AST::UnaryMinusExpression *unaryMinus = AST::cast<AST::UnaryMinusExpression *>(expr)) {
if (AST::NumericLiteral *lit = AST::cast<AST::NumericLiteral *>(unaryMinus->expression)) {
- return QDeclarativeParser::Variant(-lit->value, asString(expr));
+ return QDeclarativeParser::Variant(-lit->value, asStringRef(expr));
}
}
- return QDeclarativeParser::Variant(asString(expr), expr);
+ return QDeclarativeParser::Variant(asStringRef(expr), expr);
}
}
@@ -702,13 +739,13 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(&name->name->asString(),
location(name));
}
Property *prop = currentProperty();
- if (prop->values.count()) {
+ if (!prop->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -722,13 +759,12 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(node->statement)) {
primitive = getVariant(stmt->expression);
} else { // do binding
- primitive = QDeclarativeParser::Variant(asString(node->statement),
- node->statement);
+ primitive = QDeclarativeParser::Variant(asStringRef(node->statement), node->statement);
}
prop->location.range.length = prop->location.range.offset + prop->location.range.length - node->qualifiedId->identifierToken.offset;
prop->location.range.offset = node->qualifiedId->identifierToken.offset;
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeParser::Value *v = _parser->_pool.New<QDeclarativeParser::Value>();
v->value = primitive;
v->location = location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
@@ -748,13 +784,13 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(&name->name->asString(),
location(name));
}
Property* prop = currentProperty();
- if (prop->values.count()) {
+ if (!prop->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -843,12 +879,12 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
#ifndef QT_NO_TEXTCODEC
stream.setCodec("UTF-8");
#endif
- const QString code = stream.readAll();
+ QString *code = _pool.NewString(stream.readAll());
data = new QDeclarativeScriptParserJsASTData(fileName);
Lexer lexer(&data->engine);
- lexer.setCode(code, /*line = */ 1);
+ lexer.setCode(*code, /*line = */ 1);
Parser parser(&data->engine);
@@ -872,7 +908,7 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
if (_errors.isEmpty()) {
ProcessAST process(this);
- process(code, parser.ast());
+ process(*code, parser.ast());
// Set the url for process errors
for(int ii = 0; ii < _errors.count(); ++ii)
@@ -1198,10 +1234,6 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
void QDeclarativeScriptParser::clear()
{
- if (root) {
- root->release();
- root = 0;
- }
_imports.clear();
qDeleteAll(_refTypes);
_refTypes.clear();
@@ -1211,6 +1243,8 @@ void QDeclarativeScriptParser::clear()
delete data;
data = 0;
}
+
+ _pool.clear();
}
QDeclarativeScriptParser::TypeReference *QDeclarativeScriptParser::findOrCreateType(const QString &name)
diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h
index 73e797635a..3164d2070b 100644
--- a/src/declarative/qml/qdeclarativescriptparser_p.h
+++ b/src/declarative/qml/qdeclarativescriptparser_p.h
@@ -53,7 +53,9 @@
//
#include "qdeclarativeerror.h"
-#include "private/qdeclarativeparser_p.h"
+
+#include <private/qdeclarativeparser_p.h>
+#include <private/qdeclarativepool_p.h>
#include <QtCore/QList>
#include <QtCore/QUrl>
@@ -136,6 +138,7 @@ public:
// ### private:
QList<QDeclarativeError> _errors;
+ QDeclarativePool _pool;
QDeclarativeParser::Object *root;
QList<Import> _imports;
QList<TypeReference*> _refTypes;
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 97c5b38c20..6bda993038 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -928,7 +928,7 @@ void QDeclarativeTypeData::compile()
m_compiledData->name = m_compiledData->url.toString();
QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Compiling, m_compiledData->name);
- QDeclarativeCompiler compiler;
+ QDeclarativeCompiler compiler(&scriptParser._pool);
if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
setError(compiler.errors());
m_compiledData->release();