Use memory more conservatively during QML compilation
authorAaron Kennedy <aaron.kennedy@nokia.com>
Wed, 13 Jul 2011 04:12:21 +0000 (14:12 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 30 Aug 2011 11:18:28 +0000 (13:18 +0200)
Change-Id: I63af79e575345bce00d724f1e7c87606156d1479
Reviewed-on: http://codereview.qt.nokia.com/3744
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>

13 files changed:
src/declarative/qml/ftw/ftw.pri
src/declarative/qml/ftw/qdeclarativepool.cpp [new file with mode: 0644]
src/declarative/qml/ftw/qdeclarativepool_p.h [new file with mode: 0644]
src/declarative/qml/ftw/qfieldlist_p.h [new file with mode: 0644]
src/declarative/qml/parser/qdeclarativejsengine_p.h
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativecompiler_p.h
src/declarative/qml/qdeclarativecustomparser.cpp
src/declarative/qml/qdeclarativeparser.cpp
src/declarative/qml/qdeclarativeparser_p.h
src/declarative/qml/qdeclarativescriptparser.cpp
src/declarative/qml/qdeclarativescriptparser_p.h
src/declarative/qml/qdeclarativetypeloader.cpp

index 8709363..000c81b 100644 (file)
@@ -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 (file)
index 0000000..94bb89b
--- /dev/null
@@ -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 (file)
index 0000000..a087779
--- /dev/null
@@ -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 (file)
index 0000000..65b1d4b
--- /dev/null
@@ -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
index e366e8b..fd07f3f 100644 (file)
@@ -71,7 +71,7 @@ public:
         : _text(u, s)
     { }
 
-    const QString asString() const
+    const QString &asString() const
     { return _text; }
 
     bool operator == (const NameId &other) const
index aa7e07f..543ecb2 100644 (file)
@@ -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;
     }
 }
 
index 771a81e..7014ce2 100644 (file)
@@ -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
index ed89914..52c4f2d 100644 (file)
@@ -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) {
index d8dd729..bba2621 100644 (file)
@@ -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();
     }
 }
 
index 6a20055..496041b 100644 (file)
@@ -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);
index dcd12e2..b541511 100644 (file)
@@ -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)
index 73e7976..3164d20 100644 (file)
@@ -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;
index 97c5b38..6bda993 100644 (file)
@@ -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();