Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativecompiler.cpp
index 581a538..6c018c7 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtDeclarative module of the Qt Toolkit.
 **
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
 
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecompiler_p.h"
 
-#include "private/qdeclarativeparser_p.h"
-#include "private/qdeclarativescriptparser_p.h"
 #include "qdeclarativepropertyvaluesource.h"
 #include "qdeclarativecomponent.h"
-#include "private/qmetaobjectbuilder_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qfastmetabuilder_p.h>
+#include "qdeclarativestringconverters_p.h"
+#include "qdeclarativeengine_p.h"
 #include "qdeclarativeengine.h"
 #include "qdeclarativecontext.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "private/qdeclarativecustomparser_p_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "parser/qdeclarativejsast_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativerewrite_p.h"
+#include "qdeclarativemetatype_p.h"
+#include "qdeclarativecustomparser_p_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativecomponent_p.h"
+#include <private/qdeclarativejsast_p.h>
+#include "qdeclarativevmemetaobject_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qdeclarativeproperty_p.h"
+#include "qdeclarativerewrite_p.h"
 #include "qdeclarativescriptstring.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativescriptparser_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativev4compiler_p.h"
+#include "qdeclarativeglobal_p.h"
+#include "qdeclarativebinding_p.h"
+#include <private/qv4compiler_p.h>
 
 #include <QColor>
 #include <QDebug>
 #include <QtCore/qdebug.h>
 #include <QtCore/qdatetime.h>
 
+Q_DECLARE_METATYPE(QList<int>)
+Q_DECLARE_METATYPE(QList<qreal>)
+Q_DECLARE_METATYPE(QList<bool>)
+Q_DECLARE_METATYPE(QList<QString>)
+Q_DECLARE_METATYPE(QList<QUrl>)
+
 QT_BEGIN_NAMESPACE
 
 DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
 DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
 
-using namespace QDeclarativeParser;
+using namespace QDeclarativeJS;
+using namespace QDeclarativeScript;
+using namespace QDeclarativeCompilerTypes;
+
+static QString id_string(QLatin1String("id"));
+static QString on_string(QLatin1String("on"));
+static QString Changed_string(QLatin1String("Changed"));
+static QString Component_string(QLatin1String("Component"));
+static QString Component_import_string(QLatin1String("QML/Component"));
+static QString qsTr_string(QLatin1String("qsTr"));
+static QString qsTrId_string(QLatin1String("qsTrId"));
 
 /*!
     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), cachedComponentTypeRef(-1),
+  cachedTranslationContextIndex(-1), componentStats(0)
 {
+    if (compilerStatDump()) 
+        componentStats = pool->New<ComponentStats>();
 }
 
 /*!
@@ -113,9 +130,14 @@ QList<QDeclarativeError> QDeclarativeCompiler::errors() const
 
     Attached property names are those that start with a capital letter.
 */
-bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name)
+bool QDeclarativeCompiler::isAttachedPropertyName(const QString &name)
 {
-    return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z';
+    return isAttachedPropertyName(QHashedStringRef(&name));
+}
+
+bool QDeclarativeCompiler::isAttachedPropertyName(const QHashedStringRef &name)
+{
+    return !name.isEmpty() && name.at(0).isUpper();
 }
 
 /*!
@@ -129,15 +151,20 @@ bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name)
     character codes in property names, for simplicity and performance reasons
     QML only supports letters, numbers and underscores.
 */
-bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
+bool QDeclarativeCompiler::isSignalPropertyName(const QString &name)
+{
+    return isSignalPropertyName(QStringRef(&name));
+}
+
+bool QDeclarativeCompiler::isSignalPropertyName(const QHashedStringRef &name)
 {
     if (name.length() < 3) return false;
-    if (!name.startsWith("on")) return false;
-    int ns = name.size();
+    if (!name.startsWith(on_string)) return false;
+    int ns = name.length();
     for (int i = 2; i < ns; ++i) {
-        char curr = name.at(i);
-        if (curr == '_') continue;
-        if (curr >= 'A' && curr <= 'Z') return true;
+        const QChar curr = name.at(i);
+        if (curr.unicode() == '_') continue;
+        if (curr.isUpper()) return true;
         return false;
     }
     return false; // consists solely of underscores - invalid.
@@ -155,21 +182,23 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
     For example:
 
     \code
-    COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(QString::fromUtf8(property->name)));
+    COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(property->name));
     \endcode
 */
-#define COMPILE_EXCEPTION(token, desc) \
+#define COMPILE_EXCEPTION_LOCATION(line, column, desc) \
     {  \
-        QString exceptionDescription; \
         QDeclarativeError error; \
         error.setUrl(output->url); \
-        error.setLine((token)->location.start.line); \
-        error.setColumn((token)->location.start.column); \
+        error.setLine(line); \
+        error.setColumn(column); \
         error.setDescription(desc.trimmed()); \
         exceptions << error; \
         return false; \
     }
 
+#define COMPILE_EXCEPTION(token, desc) \
+    COMPILE_EXCEPTION_LOCATION((token)->location.start.line, (token)->location.start.column, desc)
+
 /*!
     \macro COMPILE_CHECK
     \internal
@@ -187,37 +216,50 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
     This test corresponds to action taken by genLiteralAssignment().  Any change
     made here, must have a corresponding action in genLiteralAssigment().
 */
-bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
-                                        QDeclarativeParser::Value *v)
+bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *prop,
+                                                 QDeclarativeScript::Value *v)
 {
-    QString string = v->value.asString();
+    const QDeclarativeScript::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->core.isWritable() && !prop->isReadOnlyDeclaration)
+        COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
 
-    if (prop.isEnumType()) {
-        int value;
-        if (prop.isFlagType()) {
-            value = prop.enumerator().keysToValue(string.toUtf8().constData());
+    if (prop->core.isEnum()) {
+        QMetaProperty p = prop->parent->metaObject()->property(prop->index);
+        int enumValue;
+        bool ok;
+        if (p.isFlagType()) {
+            enumValue = p.enumerator().keysToValue(value.asString().toUtf8().constData(), &ok);
         } else
-            value = prop.enumerator().keyToValue(string.toUtf8().constData());
-        if (value == -1)
+            enumValue = p.enumerator().keyToValue(value.asString().toUtf8().constData(), &ok);
+
+        if (!ok)
             COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration"));
+
+        v->value = QDeclarativeScript::Variant((double)enumValue);
         return true;
     }
-    int type = prop.userType();
+
+    int type = prop->type;
+
     switch(type) {
-        case -1:
+        case QMetaType::QVariant:
             break;
         case QVariant::String:
             if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
             break;
+        case QVariant::StringList: // we expect a string literal.  A string list is not a literal assignment.
+            if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or string list expected"));
+            break;
         case QVariant::ByteArray:
             if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: byte array expected"));
             break;
         case QVariant::Url:
             if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: url expected"));
             break;
+        case QVariant::RegExp:
+            COMPILE_EXCEPTION(v, tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
+            break;
         case QVariant::UInt:
             {
             bool ok = v->value.isNumber();
@@ -249,7 +291,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;
@@ -257,21 +299,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;
@@ -280,7 +322,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
         case QVariant::PointF:
             {
             bool ok;
-            QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+            QDeclarativeStringConverters::pointFFromString(value.asString(), &ok);
             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: point expected"));
             }
             break;
@@ -288,7 +330,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
         case QVariant::SizeF:
             {
             bool ok;
-            QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
+            QDeclarativeStringConverters::sizeFFromString(value.asString(), &ok);
             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: size expected"));
             }
             break;
@@ -296,7 +338,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
         case QVariant::RectF:
             {
             bool ok;
-            QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
+            QDeclarativeStringConverters::rectFFromString(value.asString(), &ok);
             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: rect expected"));
             }
             break;
@@ -308,261 +350,409 @@ 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;
+        case QVariant::Vector4D:
+            {
+            bool ok;
+            QDeclarativeStringConverters::vector4DFromString(value.asString(), &ok);
+            if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 4D vector expected"));
+            }
+            break;
         default:
             {
-            int t = prop.userType();
-            QDeclarativeMetaType::StringConverter converter =
-                QDeclarativeMetaType::customStringConverter(t);
+            // check if assigning a literal value to a list property.
+            // in each case, check the singular, since an Array of the specified type
+            // will not go via this literal assignment codepath.
+            if (type == qMetaTypeId<QList<qreal> >()) {
+                if (!v->value.isNumber()) {
+                    COMPILE_EXCEPTION(v, tr("Invalid property assignment: real or array of reals expected"));
+                }
+                break;
+            } else if (type == qMetaTypeId<QList<int> >()) {
+                bool ok = v->value.isNumber();
+                if (ok) {
+                    double n = v->value.asNumber();
+                    if (double(int(n)) != n)
+                        ok = false;
+                }
+                if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int or array of ints expected"));
+                break;
+            } else if (type == qMetaTypeId<QList<bool> >()) {
+                if (!v->value.isBoolean()) {
+                    COMPILE_EXCEPTION(v, tr("Invalid property assignment: bool or array of bools expected"));
+                }
+                break;
+            } else if (type == qMetaTypeId<QList<QString> >()) { // we expect a string literal.  A string list is not a literal assignment.
+                if (!v->value.isString()) {
+                    COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or array of strings expected"));
+                }
+                break;
+            } else if (type == qMetaTypeId<QList<QUrl> >()) {
+                if (!v->value.isString()) {
+                    COMPILE_EXCEPTION(v, tr("Invalid property assignment: url or array of urls expected"));
+                }
+                break;
+            }
+
+            // otherwise, check for existence of string converter to custom type
+            QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
             if (!converter)
-                COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type()))));
+                COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type))));
             }
             break;
     }
     return true;
 }
 
+static QUrl urlFromUserString(const QString &data)
+{
+    QUrl u;
+    // Preserve any valid percent-encoded octets supplied by the source
+    u.setEncodedUrl(data.toUtf8(), QUrl::TolerantMode);
+    return u;
+}
+
 /*!
     Generate a store instruction for assigning literal \a v to property \a prop.
 
     Any literal assignment that is approved in testLiteralAssignment() must have
     a corresponding action in this method.
 */
-void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
-                                       QDeclarativeParser::Value *v)
-{
-    QDeclarativeInstruction instr;
-    if (prop.isEnumType()) {
-        int value;
-        if (v->value.isNumber()) {
-            // Preresolved enum
-            value = (int)v->value.asNumber();
-        } else {
-            // Must be a string
-            if (prop.isFlagType()) {
-                value = prop.enumerator().keysToValue(v->value.asString().toUtf8().constData());
-            } else
-                value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData());
-        }
-
-        instr.setType(QDeclarativeInstruction::StoreInteger);
-        instr.storeInteger.propertyIndex = prop.propertyIndex();
-        instr.storeInteger.value = value;
+void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *prop,
+                                                QDeclarativeScript::Value *v)
+{
+    if (prop->core.isEnum()) {
+        Q_ASSERT(v->value.isNumber());
+        // Preresolved value
+        int value = (int)v->value.asNumber();
+
+        Instruction::StoreInteger instr;
+        instr.propertyIndex = prop->index;
+        instr.value = value;
         output->addInstruction(instr);
         return;
     }
 
-    QString string = v->value.asString();
-
-    int type = prop.userType();
+    int type = prop->type;
     switch(type) {
-        case -1:
+        case QMetaType::QVariant:
             {
             if (v->value.isNumber()) {
                 double n = v->value.asNumber();
                 if (double(int(n)) == n) {
-                    instr.setType(QDeclarativeInstruction::StoreVariantInteger);
-                    instr.storeInteger.propertyIndex = prop.propertyIndex();
-                    instr.storeInteger.value = int(n);
+                    if (prop->core.isVMEProperty()) {
+                        Instruction::StoreVarInteger instr;
+                        instr.propertyIndex = prop->index;
+                        instr.value = int(n);
+                        output->addInstruction(instr);
+                    } else {
+                        Instruction::StoreVariantInteger instr;
+                        instr.propertyIndex = prop->index;
+                        instr.value = int(n);
+                        output->addInstruction(instr);
+                    }
+                } else {
+                    if (prop->core.isVMEProperty()) {
+                        Instruction::StoreVarDouble instr;
+                        instr.propertyIndex = prop->index;
+                        instr.value = n;
+                        output->addInstruction(instr);
+                    } else {
+                        Instruction::StoreVariantDouble instr;
+                        instr.propertyIndex = prop->index;
+                        instr.value = n;
+                        output->addInstruction(instr);
+                    }
+                }
+            } else if (v->value.isBoolean()) {
+                if (prop->core.isVMEProperty()) {
+                    Instruction::StoreVarBool instr;
+                    instr.propertyIndex = prop->index;
+                    instr.value = v->value.asBoolean();
+                    output->addInstruction(instr);
                 } else {
-                    instr.setType(QDeclarativeInstruction::StoreVariantDouble);
-                    instr.storeDouble.propertyIndex = prop.propertyIndex();
-                    instr.storeDouble.value = n;
+                    Instruction::StoreVariantBool instr;
+                    instr.propertyIndex = prop->index;
+                    instr.value = v->value.asBoolean();
+                    output->addInstruction(instr);
                 }
-            } else if(v->value.isBoolean()) {
-                instr.setType(QDeclarativeInstruction::StoreVariantBool);
-                instr.storeBool.propertyIndex = prop.propertyIndex();
-                instr.storeBool.value = v->value.asBoolean();
             } else {
-                instr.setType(QDeclarativeInstruction::StoreVariant);
-                instr.storeString.propertyIndex = prop.propertyIndex();
-                instr.storeString.value = output->indexForString(string);
+                if (prop->core.isVMEProperty()) {
+                    Instruction::StoreVar instr;
+                    instr.propertyIndex = prop->index;
+                    instr.value = output->indexForString(v->value.asString());
+                    output->addInstruction(instr);
+                } else {
+                    Instruction::StoreVariant instr;
+                    instr.propertyIndex = prop->index;
+                    instr.value = output->indexForString(v->value.asString());
+                    output->addInstruction(instr);
+                }
             }
             }
             break;
         case QVariant::String:
             {
-            instr.setType(QDeclarativeInstruction::StoreString);
-            instr.storeString.propertyIndex = prop.propertyIndex();
-            instr.storeString.value = output->indexForString(string);
+            Instruction::StoreString instr;
+            instr.propertyIndex = prop->index;
+            instr.value = output->indexForString(v->value.asString());
+            output->addInstruction(instr);
+            }
+            break;
+        case QVariant::StringList:
+            {
+            Instruction::StoreStringList instr;
+            instr.propertyIndex = prop->index;
+            instr.value = output->indexForString(v->value.asString());
+            output->addInstruction(instr);
             }
             break;
         case QVariant::ByteArray:
             {
-            instr.setType(QDeclarativeInstruction::StoreByteArray);
-            instr.storeByteArray.propertyIndex = prop.propertyIndex();
-            instr.storeByteArray.value = output->indexForByteArray(string.toLatin1());
+            Instruction::StoreByteArray instr;
+            instr.propertyIndex = prop->index;
+            instr.value = output->indexForByteArray(v->value.asString().toLatin1());
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Url:
             {
-            instr.setType(QDeclarativeInstruction::StoreUrl);
-            QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
-            instr.storeUrl.propertyIndex = prop.propertyIndex();
-            instr.storeUrl.value = output->indexForUrl(u);
+            Instruction::StoreUrl instr;
+            QString string = v->value.asString();
+            QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(urlFromUserString(string));
+            instr.propertyIndex = prop->index;
+            instr.value = output->indexForUrl(u);
+            output->addInstruction(instr);
             }
             break;
         case QVariant::UInt:
             {
-            instr.setType(QDeclarativeInstruction::StoreInteger);
-            instr.storeInteger.propertyIndex = prop.propertyIndex();
-            instr.storeInteger.value = uint(v->value.asNumber());
+            Instruction::StoreInteger instr;
+            instr.propertyIndex = prop->index;
+            instr.value = uint(v->value.asNumber());
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Int:
             {
-            instr.setType(QDeclarativeInstruction::StoreInteger);
-            instr.storeInteger.propertyIndex = prop.propertyIndex();
-            instr.storeInteger.value = int(v->value.asNumber());
+            Instruction::StoreInteger instr;
+            instr.propertyIndex = prop->index;
+            instr.value = int(v->value.asNumber());
+            output->addInstruction(instr);
             }
             break;
         case QMetaType::Float:
             {
-            instr.setType(QDeclarativeInstruction::StoreFloat);
-            instr.storeFloat.propertyIndex = prop.propertyIndex();
-            instr.storeFloat.value = float(v->value.asNumber());
+            Instruction::StoreFloat instr;
+            instr.propertyIndex = prop->index;
+            instr.value = float(v->value.asNumber());
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Double:
             {
-            instr.setType(QDeclarativeInstruction::StoreDouble);
-            instr.storeDouble.propertyIndex = prop.propertyIndex();
-            instr.storeDouble.value = v->value.asNumber();
+            Instruction::StoreDouble instr;
+            instr.propertyIndex = prop->index;
+            instr.value = v->value.asNumber();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Color:
             {
-            QColor c = QDeclarativeStringConverters::colorFromString(string);
-            instr.setType(QDeclarativeInstruction::StoreColor);
-            instr.storeColor.propertyIndex = prop.propertyIndex();
-            instr.storeColor.value = c.rgba();
+            Instruction::StoreColor instr;
+            QColor c = QDeclarativeStringConverters::colorFromString(v->value.asString());
+            instr.propertyIndex = prop->index;
+            instr.value = c.rgba();
+            output->addInstruction(instr);
             }
             break;
 #ifndef QT_NO_DATESTRING
         case QVariant::Date:
             {
-            QDate d = QDeclarativeStringConverters::dateFromString(string);
-            instr.setType(QDeclarativeInstruction::StoreDate);
-            instr.storeDate.propertyIndex = prop.propertyIndex();
-            instr.storeDate.value = d.toJulianDay();
+            Instruction::StoreDate instr;
+            QDate d = QDeclarativeStringConverters::dateFromString(v->value.asString());
+            instr.propertyIndex = prop->index;
+            instr.value = d.toJulianDay();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Time:
             {
-            QTime time = QDeclarativeStringConverters::timeFromString(string);
-            instr.setType(QDeclarativeInstruction::StoreTime);
-            instr.storeTime.propertyIndex = prop.propertyIndex();
-            instr.storeTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time;
+            Instruction::StoreTime instr;
+            QTime time = QDeclarativeStringConverters::timeFromString(v->value.asString());
+            instr.propertyIndex = prop->index;
+            Q_ASSERT(sizeof(instr.time) == sizeof(QTime));
+            ::memcpy(&instr.time, &time, sizeof(QTime));
+            output->addInstruction(instr);
             }
             break;
         case QVariant::DateTime:
             {
-            QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(string);
+            Instruction::StoreDateTime instr;
+            QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(v->value.asString());
             QTime time = dateTime.time();
-            instr.setType(QDeclarativeInstruction::StoreDateTime);
-            instr.storeDateTime.propertyIndex = prop.propertyIndex();
-            instr.storeDateTime.date = dateTime.date().toJulianDay();
-            instr.storeDateTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time;
+            instr.propertyIndex = prop->index;
+            instr.date = dateTime.date().toJulianDay();
+            Q_ASSERT(sizeof(instr.time) == sizeof(QTime));
+            ::memcpy(&instr.time, &time, sizeof(QTime));
+            output->addInstruction(instr);
             }
             break;
 #endif // QT_NO_DATESTRING
         case QVariant::Point:
             {
+            Instruction::StorePoint instr;
             bool ok;
-            QPoint point = QDeclarativeStringConverters::pointFFromString(string, &ok).toPoint();
-            instr.setType(QDeclarativeInstruction::StorePoint);
-            instr.storePoint.propertyIndex = prop.propertyIndex();
-            instr.storePoint.point.xp = point.x();
-            instr.storePoint.point.yp = point.y();
+            QPoint point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok).toPoint();
+            instr.propertyIndex = prop->index;
+            instr.point.xp = point.x();
+            instr.point.yp = point.y();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::PointF:
             {
+            Instruction::StorePointF instr;
             bool ok;
-            QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
-            instr.setType(QDeclarativeInstruction::StorePointF);
-            instr.storePointF.propertyIndex = prop.propertyIndex();
-            instr.storePointF.point.xp = point.x();
-            instr.storePointF.point.yp = point.y();
+            QPointF point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok);
+            instr.propertyIndex = prop->index;
+            instr.point.xp = point.x();
+            instr.point.yp = point.y();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Size:
             {
+            Instruction::StoreSize instr;
             bool ok;
-            QSize size = QDeclarativeStringConverters::sizeFFromString(string, &ok).toSize();
-            instr.setType(QDeclarativeInstruction::StoreSize);
-            instr.storeSize.propertyIndex = prop.propertyIndex();
-            instr.storeSize.size.wd = size.width();
-            instr.storeSize.size.ht = size.height();
+            QSize size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok).toSize();
+            instr.propertyIndex = prop->index;
+            instr.size.wd = size.width();
+            instr.size.ht = size.height();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::SizeF:
             {
+            Instruction::StoreSizeF instr;
             bool ok;
-            QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
-            instr.setType(QDeclarativeInstruction::StoreSizeF);
-            instr.storeSizeF.propertyIndex = prop.propertyIndex();
-            instr.storeSizeF.size.wd = size.width();
-            instr.storeSizeF.size.ht = size.height();
+            QSizeF size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok);
+            instr.propertyIndex = prop->index;
+            instr.size.wd = size.width();
+            instr.size.ht = size.height();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Rect:
             {
+            Instruction::StoreRect instr;
             bool ok;
-            QRect rect = QDeclarativeStringConverters::rectFFromString(string, &ok).toRect();
-            instr.setType(QDeclarativeInstruction::StoreRect);
-            instr.storeRect.propertyIndex = prop.propertyIndex();
-            instr.storeRect.rect.x1 = rect.left();
-            instr.storeRect.rect.y1 = rect.top();
-            instr.storeRect.rect.x2 = rect.right();
-            instr.storeRect.rect.y2 = rect.bottom();
+            QRect rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok).toRect();
+            instr.propertyIndex = prop->index;
+            instr.rect.x1 = rect.left();
+            instr.rect.y1 = rect.top();
+            instr.rect.x2 = rect.right();
+            instr.rect.y2 = rect.bottom();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::RectF:
             {
+            Instruction::StoreRectF instr;
             bool ok;
-            QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
-            instr.setType(QDeclarativeInstruction::StoreRectF);
-            instr.storeRectF.propertyIndex = prop.propertyIndex();
-            instr.storeRectF.rect.xp = rect.left();
-            instr.storeRectF.rect.yp = rect.top();
-            instr.storeRectF.rect.w = rect.width();
-            instr.storeRectF.rect.h = rect.height();
+            QRectF rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok);
+            instr.propertyIndex = prop->index;
+            instr.rect.xp = rect.left();
+            instr.rect.yp = rect.top();
+            instr.rect.w = rect.width();
+            instr.rect.h = rect.height();
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Bool:
             {
+            Instruction::StoreBool instr;
             bool b = v->value.asBoolean();
-            instr.setType(QDeclarativeInstruction::StoreBool);
-            instr.storeBool.propertyIndex = prop.propertyIndex();
-            instr.storeBool.value = b;
+            instr.propertyIndex = prop->index;
+            instr.value = b;
+            output->addInstruction(instr);
             }
             break;
         case QVariant::Vector3D:
             {
+            Instruction::StoreVector3D instr;
+            bool ok;
+            QVector3D vector = QDeclarativeStringConverters::vector3DFromString(v->value.asString(), &ok);
+            instr.propertyIndex = prop->index;
+            instr.vector.xp = vector.x();
+            instr.vector.yp = vector.y();
+            instr.vector.zp = vector.z();
+            output->addInstruction(instr);
+            }
+            break;
+    case QVariant::Vector4D:
+            {
+            Instruction::StoreVector4D instr;
             bool ok;
-            QVector3D vector = QDeclarativeStringConverters::vector3DFromString(string, &ok);
-            instr.setType(QDeclarativeInstruction::StoreVector3D);
-            instr.storeVector3D.propertyIndex = prop.propertyIndex();
-            instr.storeVector3D.vector.xp = vector.x();
-            instr.storeVector3D.vector.yp = vector.y();
-            instr.storeVector3D.vector.zp = vector.z();
+            QVector4D vector = QDeclarativeStringConverters::vector4DFromString(v->value.asString(), &ok);
+            instr.propertyIndex = prop->index;
+            instr.vector.xp = vector.x();
+            instr.vector.yp = vector.y();
+            instr.vector.zp = vector.z();
+            instr.vector.wp = vector.w();
+            output->addInstruction(instr);
             }
             break;
         default:
             {
-            int t = prop.userType();
-            instr.setType(QDeclarativeInstruction::AssignCustomType);
-            instr.assignCustomType.propertyIndex = prop.propertyIndex();
-            instr.assignCustomType.primitive = output->indexForString(string);
-            instr.assignCustomType.type = t;
+            // generate single literal value assignment to a list property if required
+            if (type == qMetaTypeId<QList<qreal> >()) {
+                Instruction::StoreDoubleQList instr;
+                instr.propertyIndex = prop->index;
+                instr.value = v->value.asNumber();
+                output->addInstruction(instr);
+                break;
+            } else if (type == qMetaTypeId<QList<int> >()) {
+                Instruction::StoreIntegerQList instr;
+                instr.propertyIndex = prop->index;
+                instr.value = int(v->value.asNumber());
+                output->addInstruction(instr);
+                break;
+            } else if (type == qMetaTypeId<QList<bool> >()) {
+                Instruction::StoreBoolQList instr;
+                bool b = v->value.asBoolean();
+                instr.propertyIndex = prop->index;
+                instr.value = b;
+                output->addInstruction(instr);
+                break;
+            } else if (type == qMetaTypeId<QList<QUrl> >()) {
+                Instruction::StoreUrlQList instr;
+                QString string = v->value.asString();
+                QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(urlFromUserString(string));
+                instr.propertyIndex = prop->index;
+                instr.value = output->indexForUrl(u);
+                output->addInstruction(instr);
+                break;
+            } else if (type == qMetaTypeId<QList<QString> >()) {
+                Instruction::StoreStringQList instr;
+                instr.propertyIndex = prop->index;
+                instr.value = output->indexForString(v->value.asString());
+                output->addInstruction(instr);
+                break;
+            }
+
+            // otherwise, generate custom type literal assignment
+            Instruction::AssignCustomType instr;
+            instr.propertyIndex = prop->index;
+            instr.primitive = output->indexForString(v->value.asString());
+            instr.type = type;
+            output->addInstruction(instr);
             }
             break;
     }
-    output->addInstruction(instr);
 }
 
 /*!
@@ -573,7 +763,7 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data)
     data->types.clear();
     data->primitives.clear();
     data->datas.clear();
-    data->bytecode.clear();
+    data->bytecode.resize(0);
 }
 
 /*!
@@ -596,17 +786,24 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
     Q_ASSERT(out);
     reset(out);
 
-    output = out;
+    QDeclarativeScript::Object *root = unit->parser().tree();
+    Q_ASSERT(root);
+
+    this->engine = engine;
+    this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
+    this->unit = unit;
+    this->unitRoot = root;
+    this->output = out;
 
     // Compile types
     const QList<QDeclarativeTypeData::TypeReference>  &resolvedTypes = unit->resolvedTypes();
-    QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
+    QList<QDeclarativeScript::TypeReference *> referencedTypes = unit->parser().referencedTypes();
 
     for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
         QDeclarativeCompiledData::TypeReference ref;
 
         const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
-        QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
+        QDeclarativeScript::TypeReference *parserRef = referencedTypes.at(ii);
 
         if (tref.type) {
             ref.type = tref.type;
@@ -619,112 +816,115 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
             
             if (ref.type->containsRevisionedAttributes()) {
                 QDeclarativeError cacheError;
-                ref.typePropertyCache = 
-                    QDeclarativeEnginePrivate::get(engine)->cache(ref.type, resolvedTypes.at(ii).minorVersion, cacheError);
-
-                if (!ref.typePropertyCache) {
+                ref.typePropertyCache = enginePrivate->cache(ref.type, resolvedTypes.at(ii).minorVersion, 
+                                                             cacheError);
+                if (!ref.typePropertyCache) 
                     COMPILE_EXCEPTION(parserRef->refObjects.first(), cacheError.description());
-                }
                 ref.typePropertyCache->addref();
             }
 
         } else if (tref.typeData) {
             ref.component = tref.typeData->compiledData();
         }
-        ref.className = parserRef->name.toUtf8();
+        ref.className = parserRef->name;
         out->types << ref;
     }
 
-    QDeclarativeParser::Object *root = unit->parser().tree();
-    Q_ASSERT(root);
-
-    this->engine = engine;
-    this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
-    this->unit = unit;
-    this->unitRoot = root;
     compileTree(root);
 
     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;
     this->unit = 0;
+    this->cachedComponentTypeRef = -1;
+    this->cachedTranslationContextIndex = -1;
     this->unitRoot = 0;
 
     return !isError();
 }
 
-void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
+void QDeclarativeCompiler::compileTree(QDeclarativeScript::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;
+    // We generate the importCache before we build the tree so that
+    // it can be used in the binding compiler.  Given we "expect" the
+    // QML compilation to succeed, this isn't a waste.
+    output->importCache = new QDeclarativeTypeNameCache();
+    foreach (const QString &ns, unit->namespaces()) {
+        output->importCache->add(ns);
+    }
 
+    int scriptIndex = 0;
     foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
-        importedScriptIndexes.append(script.qualifier);
+        QString qualifier = script.qualifier;
+        QString enclosingNamespace;
 
-        QDeclarativeInstruction import;
-        import.setType(QDeclarativeInstruction::StoreImportedScript);
-        import.storeScript.value = output->scripts.count();
+        const int lastDotIndex = qualifier.lastIndexOf(QLatin1Char('.'));
+        if (lastDotIndex != -1) {
+            enclosingNamespace = qualifier.left(lastDotIndex);
+            qualifier = qualifier.mid(lastDotIndex+1);
+        }
 
-        QDeclarativeScriptData *scriptData = script.script->scriptData();
-        scriptData->addref();
-        output->scripts << scriptData;
-        output->addInstruction(import);
+        output->importCache->add(qualifier, scriptIndex++, enclosingNamespace);
     }
 
-    // We generate the importCache before we build the tree so that
-    // it can be used in the binding compiler.  Given we "expect" the
-    // QML compilation to succeed, this isn't a waste.
-    output->importCache = new QDeclarativeTypeNameCache(engine);
-    for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) 
-        output->importCache->add(importedScriptIndexes.at(ii), ii);
     unit->imports().populateCache(output->importCache, engine);
 
     if (!buildObject(tree, BindingContext()) || !completeComponentBuild())
         return;
 
-    QDeclarativeInstruction init;
-    init.setType(QDeclarativeInstruction::Init);
-    init.init.bindingsSize = compileState.bindings.count();
-    init.init.parserStatusSize = compileState.parserStatusCount;
-    init.init.contextCache = genContextCache();
-    if (compileState.compiledBindingData.isEmpty())
-        init.init.compiledBinding = -1;
+    Instruction::Init init;
+    init.bindingsSize = compileState->totalBindingsCount;
+    init.parserStatusSize = compileState->parserStatusCount;
+    init.contextCache = genContextCache();
+    init.objectStackSize = compileState->objectDepth.maxDepth();
+    init.listStackSize = compileState->listDepth.maxDepth();
+    if (compileState->compiledBindingData.isEmpty())
+        init.compiledBinding = -1;
     else
-        init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+        init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
     output->addInstruction(init);
 
-    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;
+    foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+        Instruction::StoreImportedScript import;
+        import.value = output->scripts.count();
+
+        QDeclarativeScriptData *scriptData = script.script->scriptData();
+        scriptData->addref();
+        output->scripts << scriptData;
+        output->addInstruction(import);
+    }
+
+    if (!compileState->v8BindingProgram.isEmpty()) {
+        Instruction::InitV8Bindings bindings;
+        bindings.program = output->indexForString(compileState->v8BindingProgram);
+        bindings.programIndex = compileState->v8BindingProgramIndex;
+        bindings.line = compileState->v8BindingProgramLine;
         output->addInstruction(bindings);
     }
 
     genObject(tree);
 
-    QDeclarativeInstruction def;
-    def.setType(QDeclarativeInstruction::SetDefault);
+    Instruction::SetDefault def;
     output->addInstruction(def);
 
-    QDeclarativeInstruction done;
-    done.setType(QDeclarativeInstruction::Done);
+    Instruction::Done done;
     output->addInstruction(done);
 
     Q_ASSERT(tree->metatype);
@@ -739,25 +939,26 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
         enginePrivate->registerCompositeType(output);
 }
 
-static bool ValuePtrLessThan(const QDeclarativeParser::Value *t1, const QDeclarativeParser::Value *t2)
+static bool QStringList_contains(const QStringList &list, const QHashedStringRef &string)
 {
-    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);
+    for (int ii = 0; ii < list.count(); ++ii)
+        if (string == list.at(ii))
+            return true;
+
+    return false;
 }
 
-bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildObject(QDeclarativeScript::Object *obj, const BindingContext &ctxt)
 {
-    componentStat.objects++;
+    if (componentStats)
+        componentStats->componentStat.objects++;
 
     Q_ASSERT (obj->type != -1);
-    const QDeclarativeCompiledData::TypeReference &tr =
-        output->types.at(obj->type);
+    const QDeclarativeCompiledData::TypeReference &tr = output->types.at(obj->type);
     obj->metatype = tr.metaObject();
 
-    if (tr.type)
+    if (tr.type) 
         obj->typeName = tr.type->qmlTypeName();
-    obj->className = tr.className;
 
     // This object is a "Component" element
     if (tr.type && obj->metatype == &QDeclarativeComponent::staticMetaObject) {
@@ -765,6 +966,20 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
         return true;
     } 
 
+    if (tr.component) {
+        typedef QDeclarativeInstruction I; 
+        const I *init = ((const I *)tr.component->bytecode.constData());
+        Q_ASSERT(init && tr.component->instructionType(init) == QDeclarativeInstruction::Init);
+        // Adjust stack depths to include nested components
+        compileState->objectDepth.pushPop(init->init.objectStackSize);
+        compileState->listDepth.pushPop(init->init.listStackSize);
+        compileState->parserStatusCount += init->init.parserStatusSize;
+        compileState->totalBindingsCount += init->init.bindingsSize;
+    }
+
+    compileState->objectDepth.push();
+
     // Object instantiations reset the binding context
     BindingContext objCtxt(obj);
 
@@ -778,7 +993,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
@@ -793,8 +1008,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") {
+    for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+        if (prop->name() == id_string) {
             COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
             break;
         }
@@ -804,34 +1019,75 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
     Property *defaultProperty = 0;
     Property *skipProperty = 0;
     if (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);
+        defaultProperty = obj->defaultProperty;
+
+        Property *explicitProperty = 0;
+
+        const QMetaObject *mo = obj->metatype;
+        int idx = mo->indexOfClassInfo("DefaultProperty"); 
+        if (idx != -1) {
+            QMetaClassInfo info = mo->classInfo(idx);
+            const char *p = info.value();
+            if (p) {
+                int plen = 0;
+                char ord = 0;
+                while (char c = p[plen++]) { ord |= c; };
+                --plen;
+
+                if (ord & 0x80) {
+                    // Utf8 - unoptimal, but seldom hit
+                    QString *s = pool->NewString(QString::fromUtf8(p, plen));
+                    QHashedStringRef r(*s);
+
+                    if (obj->propertiesHashField.test(r.hash())) {
+                        for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+                            if (ep->name() == r) {
+                                explicitProperty = ep;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (!explicitProperty)
+                        defaultProperty->setName(r);
 
-            } else {
-                defaultProperty = obj->defaultProperty;
-                defaultProperty->addref();
+                } else {
+                    QHashedCStringRef r(p, plen); 
+
+                    if (obj->propertiesHashField.test(r.hash())) {
+                        for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+                            if (ep->name() == r) {
+                                explicitProperty = ep;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (!explicitProperty) {
+                        // Set the default property name
+                        QChar *buffer = pool->NewRawArray<QChar>(r.length());
+                        r.writeUtf16(buffer);
+                        defaultProperty->setName(QHashedStringRef(buffer, r.length(), r.hash()));
+                    }
+                }
             }
-        } else {
-            defaultProperty = obj->defaultProperty;
-            defaultProperty->addref();
         }
+
+        if (explicitProperty && !explicitProperty->value && !explicitProperty->values.isEmpty()) {
+
+            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);
+        } 
     }
 
     QDeclarativeCustomParser *cp = 0;
@@ -839,36 +1095,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")
+        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();
+                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(QString::fromUtf8(prop->name)))
+        if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name()))
             prop->isDeferred = true;
 
     }
@@ -880,26 +1138,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(QString::fromUtf8(prop->name)))
+        if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name()))
             prop->isDeferred = true;
     }
 
-    if (defaultProperty) 
-        defaultProperty->release();
-
     // Compile custom parser parts
     if (isCustomParser && !customProps.isEmpty()) {
         cp->clearErrors();
@@ -914,10 +1168,12 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
         }
     }
 
+    compileState->objectDepth.pop();
+
     return true;
 }
 
-void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genObject(QDeclarativeScript::Object *obj)
 {
     QDeclarativeCompiledData::TypeReference &tr = output->types[obj->type];
     if (tr.type && obj->metatype == &QDeclarativeComponent::staticMetaObject) {
@@ -927,46 +1183,55 @@ 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) {
-
-        QDeclarativeInstruction create;
-        create.setType(QDeclarativeInstruction::CreateSimpleObject);
-        create.createSimple.create = output->types.at(obj->type).type->createFunction();
-        create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
-        create.createSimple.type = obj->type;
-        create.createSimple.line = obj->location.start.line;
-        create.createSimple.column = obj->location.start.column;
+        !output->types.at(obj->type).type->isExtendedType() && obj != compileState->root) {
+
+        Instruction::CreateSimpleObject create;
+        create.create = output->types.at(obj->type).type->createFunction();
+        create.typeSize = output->types.at(obj->type).type->createSize();
+        create.type = obj->type;
+        create.line = obj->location.start.line;
+        create.column = obj->location.start.column;
         output->addInstruction(create);
 
     } else {
 
-        QDeclarativeInstruction create;
-        create.setType(QDeclarativeInstruction::CreateObject);
-        create.create.line = obj->location.start.line;
-        create.create.column = obj->location.start.column;
-        create.create.data = -1;
-        if (!obj->custom.isEmpty())
-            create.create.data = output->indexForByteArray(obj->custom);
-        create.create.type = obj->type;
-        if (!output->types.at(create.create.type).type && 
-            !obj->bindingBitmask.isEmpty()) {
-            Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
-            create.create.bindingBits = 
-                output->indexForByteArray(obj->bindingBitmask);
+        if (output->types.at(obj->type).type) {
+            Instruction::CreateCppObject create;
+            create.line = obj->location.start.line;
+            create.column = obj->location.start.column;
+            create.data = -1;
+            if (!obj->custom.isEmpty())
+                create.data = output->indexForByteArray(obj->custom);
+            create.type = obj->type;
+            create.isRoot = (compileState->root == obj);
+            output->addInstruction(create);
         } else {
-            create.create.bindingBits = -1;
-        }
-        output->addInstruction(create);
+            Instruction::CreateQMLObject create;
+            create.type = obj->type;
+            create.isRoot = (compileState->root == obj);
+
+            if (!obj->bindingBitmask.isEmpty()) {
+                Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
+                create.bindingBits = output->indexForByteArray(obj->bindingBitmask);
+            } else {
+                create.bindingBits = -1;
+            }
+            output->addInstruction(create);
 
+            Instruction::CompleteQMLObject complete;
+            complete.line = obj->location.start.line;
+            complete.column = obj->location.start.column;
+            complete.isRoot = (compileState->root == obj);
+            output->addInstruction(complete);
+        }
     }
 
     // Setup the synthesized meta object if necessary
     if (!obj->metadata.isEmpty()) {
-        QDeclarativeInstruction meta;
-        meta.setType(QDeclarativeInstruction::StoreMetaObject);
-        meta.storeMeta.data = output->indexForByteArray(obj->metadata);
-        meta.storeMeta.aliasData = output->indexForByteArray(obj->synthdata);
-        meta.storeMeta.propertyCache = output->propertyCaches.count();
+        Instruction::StoreMetaObject meta;
+        meta.data = output->indexForByteArray(obj->metadata);
+        meta.aliasData = output->indexForByteArray(obj->synthdata);
+        meta.propertyCache = output->propertyCaches.count();
 
         QDeclarativePropertyCache *propertyCache = obj->synthCache;
         Q_ASSERT(propertyCache);
@@ -978,8 +1243,8 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
                 reinterpret_cast<const QDeclarativeVMEMetaData *>(obj->synthdata.constData());
             for (int ii = 0; ii < vmeMetaData->aliasCount; ++ii) {
                 int index = obj->metaObject()->propertyOffset() + vmeMetaData->propertyCount + ii;
-                QDeclarativePropertyCache::Data *data = propertyCache->property(index);
-                data->setFlags(data->getFlags() | QDeclarativePropertyCache::Data::IsAlias);
+                QDeclarativePropertyData *data = propertyCache->property(index);
+                data->setFlags(data->getFlags() | QDeclarativePropertyData::IsAlias);
             }
         }
 
@@ -997,41 +1262,40 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
 
     // Set the object id
     if (!obj->id.isEmpty()) {
-        QDeclarativeInstruction id;
-        id.setType(QDeclarativeInstruction::SetId);
-        id.setId.value = output->indexForString(obj->id);
-        id.setId.index = obj->idIndex;
+        Instruction::SetId id;
+        id.value = output->indexForString(obj->id);
+        id.index = obj->idIndex;
         output->addInstruction(id);
     }
 
     // Begin the class
     if (tr.type && obj->parserStatusCast != -1) {
-        QDeclarativeInstruction begin;
-        begin.setType(QDeclarativeInstruction::BeginObject);
-        begin.begin.castValue = obj->parserStatusCast;
+        Instruction::BeginObject begin;
+        begin.castValue = obj->parserStatusCast;
         output->addInstruction(begin);
     }
 
     genObjectBody(obj);
 }
 
-void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genObjectBody(QDeclarativeScript::Object *obj)
 {
-    typedef QPair<Property *, int> PropPair;
-    foreach(const PropPair &prop, obj->scriptStringProperties) {
-        const QString &script = prop.first->values.at(0)->value.asScript();
-        QDeclarativeInstruction ss;
-        ss.setType(QDeclarativeInstruction::StoreScriptString);
-        ss.storeScriptString.propertyIndex = prop.first->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;
+    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();
+        Instruction::StoreScriptString ss;
+        ss.propertyIndex = prop->index;
+        ss.value = output->indexForString(script);
+        ss.scope = prop->scriptStringScope;
+//        ss.bindingId = rewriteBinding(script, prop->name());
+        ss.bindingId = rewriteBinding(prop->values.first()->value, QString()); // XXX
+        ss.line = prop->location.start.line;
+        ss.column = prop->location.start.column;
         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;
@@ -1040,198 +1304,184 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
             genValueProperty(prop, obj);
     }
     if (seenDefer) {
-        QDeclarativeInstruction defer;
-        defer.setType(QDeclarativeInstruction::Defer);
-        defer.defer.deferCount = 0;
+        Instruction::Defer defer;
+        defer.deferCount = 0;
         int deferIdx = output->addInstruction(defer);
         int nextInstructionIndex = output->nextInstructionIndex();
 
-        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.contextCache = -1;
-        init.init.compiledBinding = -1;
-        output->addInstruction(init);
+        Instruction::DeferInit dinit;
+        // XXX - these are now massive over allocations
+        dinit.bindingsSize = compileState->totalBindingsCount;
+        dinit.parserStatusSize = compileState->parserStatusCount; 
+        dinit.objectStackSize = compileState->objectDepth.maxDepth(); 
+        dinit.listStackSize = compileState->listDepth.maxDepth(); 
+        output->addInstruction(dinit);
 
-        foreach(Property *prop, obj->valueProperties) {
+        for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
             if (!prop->isDeferred)
                 continue;
             genValueProperty(prop, obj);
         }
 
-        QDeclarativeInstruction done;
-        done.setType(QDeclarativeInstruction::Done);
+        Instruction::Done done;
         output->addInstruction(done);
 
         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);
+        QDeclarativeScript::Value *v = prop->values.first();
 
         if (v->type == Value::SignalObject) {
 
             genObject(v->object);
 
-            QDeclarativeInstruction assign;
-            assign.setType(QDeclarativeInstruction::AssignSignalObject);
-            assign.assignSignalObject.line = v->location.start.line;
-            assign.assignSignalObject.signal =
-                output->indexForByteArray(prop->name);
+            Instruction::AssignSignalObject assign;
+            assign.line = v->location.start.line;
+            assign.signal = output->indexForString(prop->name().toString());
             output->addInstruction(assign);
 
         } else if (v->type == Value::SignalExpression) {
 
-            BindingContext ctxt = compileState.signalExpressions.value(v);
-
-            QDeclarativeInstruction store;
-            store.setType(QDeclarativeInstruction::StoreSignal);
-            store.storeSignal.signalIndex = prop->index;
-            store.storeSignal.value =
-                output->indexForString(v->value.asScript().trimmed());
-            store.storeSignal.context = ctxt.stack;
-            store.storeSignal.name = output->indexForByteArray(prop->name);
-            store.storeSignal.line = v->location.start.line;
+            Instruction::StoreSignal store;
+            store.signalIndex = prop->index;
+            QDeclarativeRewrite::RewriteSignalHandler rewriteSignalHandler;
+            const QString &rewrite =
+                    rewriteSignalHandler(v->value.asScript().trimmed(), prop->name().toString());
+            store.value = output->indexForString(rewrite);
+            store.context = v->signalExpressionContextStack;
+            store.line = v->location.start.line;
+            store.column = v->location.start.column;
             output->addInstruction(store);
 
         }
 
     }
 
-    foreach(Property *prop, obj->attachedProperties) {
-        QDeclarativeInstruction fetch;
-        fetch.setType(QDeclarativeInstruction::FetchAttached);
-        fetch.fetchAttached.id = prop->index;
-        fetch.fetchAttached.line = prop->location.start.line;
+    for (Property *prop = obj->attachedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
+        Instruction::FetchAttached fetch;
+        fetch.id = prop->index;
+        fetch.line = prop->location.start.line;
         output->addInstruction(fetch);
 
         genObjectBody(prop->value);
 
-        QDeclarativeInstruction pop;
-        pop.setType(QDeclarativeInstruction::PopFetchedObject);
+        Instruction::PopFetchedObject pop;
         output->addInstruction(pop);
     }
 
-    foreach(Property *prop, obj->groupedProperties) {
-        QDeclarativeInstruction fetch;
-        fetch.setType(QDeclarativeInstruction::FetchObject);
-        fetch.fetch.property = prop->index;
-        fetch.fetch.line = prop->location.start.line;
+    for (Property *prop = obj->groupedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
+        Instruction::FetchObject fetch;
+        fetch.property = prop->index;
+        fetch.line = prop->location.start.line;
         output->addInstruction(fetch);
 
         if (!prop->value->metadata.isEmpty()) {
-            QDeclarativeInstruction meta;
-            meta.setType(QDeclarativeInstruction::StoreMetaObject);
-            meta.storeMeta.data = output->indexForByteArray(prop->value->metadata);
-            meta.storeMeta.aliasData = output->indexForByteArray(prop->value->synthdata);
-            meta.storeMeta.propertyCache = -1;
+            Instruction::StoreMetaObject meta;
+            meta.data = output->indexForByteArray(prop->value->metadata);
+            meta.aliasData = output->indexForByteArray(prop->value->synthdata);
+            meta.propertyCache = -1;
             output->addInstruction(meta);
         }
 
         genObjectBody(prop->value);
 
-        QDeclarativeInstruction pop;
-        pop.setType(QDeclarativeInstruction::PopFetchedObject);
+        Instruction::PopFetchedObject pop;
         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);
     }
 }
 
-void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop)
+void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeScript::Object *obj,QDeclarativeScript::Property *prop)
 {
-    QDeclarativeInstruction fetch;
-    fetch.setType(QDeclarativeInstruction::FetchValueType);
-    fetch.fetchValue.property = prop->index;
-    fetch.fetchValue.type = prop->type;
-    fetch.fetchValue.bindingSkipList = 0;
+    Instruction::FetchValueType fetch;
+    fetch.property = prop->index;
+    fetch.type = prop->type;
+    fetch.bindingSkipList = 0;
 
     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);
+                fetch.bindingSkipList |= (1 << vprop->index);
             }
         }
     }
 
     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);
     }
 
-    QDeclarativeInstruction pop;
-    pop.setType(QDeclarativeInstruction::PopValueType);
-    pop.fetchValue.property = prop->index;
-    pop.fetchValue.type = prop->type;
-    pop.fetchValue.bindingSkipList = 0;
+    Instruction::PopValueType pop;
+    pop.property = prop->index;
+    pop.type = prop->type;
+    pop.bindingSkipList = 0;
     output->addInstruction(pop);
 }
 
-void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genComponent(QDeclarativeScript::Object *obj)
 {
-    QDeclarativeParser::Object *root = obj->defaultProperty->values.at(0)->object;
+    QDeclarativeScript::Object *root = obj->defaultProperty->values.first()->object;
     Q_ASSERT(root);
 
-    QDeclarativeInstruction create;
-    create.setType(QDeclarativeInstruction::CreateComponent);
-    create.createComponent.line = root->location.start.line;
-    create.createComponent.column = root->location.start.column;
-    create.createComponent.endLine = root->location.end.line;
+    Instruction::CreateComponent create;
+    create.line = root->location.start.line;
+    create.column = root->location.start.column;
+    create.endLine = root->location.end.line;
+    create.isRoot = (compileState->root == 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.contextCache = genContextCache();
-    if (compileState.compiledBindingData.isEmpty())
-        init.init.compiledBinding = -1;
+    Instruction::Init init;
+    init.bindingsSize = compileState->totalBindingsCount;
+    init.parserStatusSize = compileState->parserStatusCount;
+    init.contextCache = genContextCache();
+    init.objectStackSize = compileState->objectDepth.maxDepth();
+    init.listStackSize = compileState->listDepth.maxDepth();
+    if (compileState->compiledBindingData.isEmpty())
+        init.compiledBinding = -1;
     else
-        init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+        init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
     output->addInstruction(init);
 
-    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;
+    if (!compileState->v8BindingProgram.isEmpty()) {
+        Instruction::InitV8Bindings bindings;
+        bindings.program = output->indexForString(compileState->v8BindingProgram);
+        bindings.programIndex = compileState->v8BindingProgramIndex;
+        bindings.line = compileState->v8BindingProgramLine;
         output->addInstruction(bindings);
     }
 
     genObject(root);
 
-    QDeclarativeInstruction def;
-    def.setType(QDeclarativeInstruction::SetDefault);
+    Instruction::SetDefault def;
     output->addInstruction(def);
 
-    QDeclarativeInstruction done;
-    done.setType(QDeclarativeInstruction::Done);
+    Instruction::Done done;
     output->addInstruction(done);
 
     output->instruction(createInstruction)->createComponent.count = 
@@ -1240,10 +1490,9 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
     compileState = oldCompileState;
 
     if (!obj->id.isEmpty()) {
-        QDeclarativeInstruction id;
-        id.setType(QDeclarativeInstruction::SetId);
-        id.setId.value = output->indexForString(obj->id);
-        id.setId.index = obj->idIndex;
+        Instruction::SetId id;
+        id.value = output->indexForString(obj->id);
+        id.index = obj->idIndex;
         output->addInstruction(id);
     }
 
@@ -1253,29 +1502,31 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
     }
 }
 
-bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildComponent(QDeclarativeScript::Object *obj,
                                  const BindingContext &ctxt)
 {
     // The special "Component" element can only have the id property and a
     // default property, that actually defines the component's tree
 
+    compileState->objectDepth.push();
+
     // 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"))
-        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.value(idVal))
             COMPILE_EXCEPTION(idProp, tr("id is not unique"));
 
         obj->id = idVal;
@@ -1284,8 +1535,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())
@@ -1295,8 +1546,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
     if (!obj->dynamicSlots.isEmpty())
         COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
 
-    QDeclarativeParser::Object *root = 0;
-    if (obj->defaultProperty && obj->defaultProperty->values.count())
+    QDeclarativeScript::Object *root = 0;
+    if (obj->defaultProperty && !obj->defaultProperty->values.isEmpty())
         root = obj->defaultProperty->values.first()->object;
 
     if (!root)
@@ -1305,29 +1556,39 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
     // Build the component tree
     COMPILE_CHECK(buildComponentFromRoot(root, ctxt));
 
+    compileState->objectDepth.pop();
+
     return true;
 }
 
-bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeScript::Object *obj,
                                          const BindingContext &ctxt)
 {
-    ComponentCompileState oldComponentCompileState = compileState;
-    ComponentStat oldComponentStat = componentStat;
+    ComponentCompileState *oldComponentCompileState = compileState;
+    compileState = pool->New<ComponentCompileState>();
+    compileState->root = obj;
+    compileState->nested = true;
+
+    if (componentStats) {
+        ComponentStat oldComponentStat = componentStats->componentStat;
 
-    compileState = ComponentCompileState();
-    compileState.root = obj;
-    compileState.nested = true;
+        componentStats->componentStat = ComponentStat();
+        componentStats->componentStat.lineNumber = obj->location.start.line;
 
-    componentStat = ComponentStat();
-    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;
 }
@@ -1336,15 +1597,15 @@ bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *ob
 // Build a sub-object.  A sub-object is one that was not created directly by
 // QML - such as a grouped property object, or an attached object.  Sub-object's
 // can't have an id, involve a custom parser, have attached properties etc.
-bool QDeclarativeCompiler::buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildSubObject(QDeclarativeScript::Object *obj, const BindingContext &ctxt)
 {
     Q_ASSERT(obj->metatype);
     Q_ASSERT(!obj->defaultProperty);
     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));
@@ -1356,49 +1617,70 @@ bool QDeclarativeCompiler::buildSubObject(QDeclarativeParser::Object *obj, const
 
 int QDeclarativeCompiler::componentTypeRef()
 {
-    QDeclarativeType *t = QDeclarativeMetaType::qmlType("QtQuick/Component",2,0);
-    for (int ii = output->types.count() - 1; ii >= 0; --ii) {
-        if (output->types.at(ii).type == t)
-            return ii;
+    if (cachedComponentTypeRef == -1) {
+        QDeclarativeType *t = QDeclarativeMetaType::qmlType(Component_import_string,1,0);
+        for (int ii = output->types.count() - 1; ii >= 0; --ii) {
+            if (output->types.at(ii).type == t) {
+                cachedComponentTypeRef = ii;
+                return ii;
+            }
+        }
+        QDeclarativeCompiledData::TypeReference ref;
+        ref.className = Component_string;
+        ref.type = t;
+        output->types << ref;
+        cachedComponentTypeRef = output->types.count() - 1;
     }
-    QDeclarativeCompiledData::TypeReference ref;
-    ref.className = "Component";
-    ref.type = t;
-    output->types << ref;
-    return output->types.count() - 1;
+    return cachedComponentTypeRef;
 }
 
-bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
+int QDeclarativeCompiler::translationContextIndex()
+{
+    if (cachedTranslationContextIndex == -1) {
+        // This code must match that in the qsTr() implementation
+        QString path = output->url.toString();
+        int lastSlash = path.lastIndexOf(QLatin1Char('/'));
+        QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) :
+                                             QString();
+        QByteArray contextUtf8 = context.toUtf8();
+        cachedTranslationContextIndex = output->indexForByteArray(contextUtf8);
+    }
+    return cachedTranslationContextIndex;
+}
+
+bool QDeclarativeCompiler::buildSignal(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj,
                                        const BindingContext &ctxt)
 {
     Q_ASSERT(obj->metaObject());
 
-    QByteArray name = prop->name;
-    Q_ASSERT(name.startsWith("on"));
-    name = name.mid(2);
+    const QHashedStringRef &propName = prop->name();
+
+    Q_ASSERT(propName.startsWith(on_string));
+    QString name = propName.mid(2, -1).toString();
 
     // Note that the property name could start with any alpha or '_' or '$' character,
     // so we need to do the lower-casing of the first alpha character.
     for (int firstAlphaIndex = 0; firstAlphaIndex < name.size(); ++firstAlphaIndex) {
-        if (name[firstAlphaIndex] >= 'A' && name[firstAlphaIndex] <= 'Z') {
-            name[firstAlphaIndex] = name[firstAlphaIndex] - 'A' + 'a';
+        if (name.at(firstAlphaIndex).isUpper()) {
+            name[firstAlphaIndex] = name.at(firstAlphaIndex).toLower();
             break;
         }
     }
 
     bool notInRevision = false;
-    int sigIdx = indexOfSignal(obj, name, &notInRevision);
 
-    if (sigIdx == -1) {
+    QDeclarativePropertyData *sig = signal(obj, QStringRef(&name), &notInRevision);
 
-        if (notInRevision && -1 == indexOfProperty(obj, prop->name, 0)) {
+    if (sig == 0) {
+
+        if (notInRevision && 0 == property(obj, propName, 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(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(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().toString()).arg(type.type->module()).arg(type.majorVersion).arg(type.minorVersion));
             } else {
-                COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
+                COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString()));
             }
         }
 
@@ -1408,26 +1690,28 @@ 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;
+        prop->index = sig->coreIndex;
+        prop->core = *sig;
+
         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);
+            prop->values.first()->signalExpressionContextStack = ctxt.stack;
         }
     }
 
@@ -1438,37 +1722,28 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
 /*!
     Returns true if (value) property \a prop exists on obj, false otherwise.
 */
-bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
-                                             QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeScript::Property *prop,
+                                             QDeclarativeScript::Object *obj)
 {
-    if(isAttachedPropertyName(prop->name) || prop->name == "id")
+    if (prop->name().isEmpty())
+        return false;
+    if(isAttachedPropertyName(prop->name()) || prop->name() == id_string)
         return true;
 
-    const QMetaObject *mo = obj->metaObject();
-    if (mo) {
-        if (prop->isDefault) {
-            QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
-            return p.name() != 0;
-        } else {
-            int idx = indexOfProperty(obj, prop->name);
-            return idx != -1 && mo->property(idx).isScriptable();
-        }
-    }
-
-    return false;
+    return property(obj, prop->name()) != 0;
 }
 
-bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
-                                QDeclarativeParser::Object *obj,
-                                const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildProperty(QDeclarativeScript::Property *prop,
+                                         QDeclarativeScript::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()) {
@@ -1480,7 +1755,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
 
         QDeclarativeType *type = 0;
         QDeclarativeImportedNamespace *typeNamespace = 0;
-        unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
+        unit->imports().resolveType(prop->name().toString(), &type, 0, 0, 0, &typeNamespace);
 
         if (typeNamespace) {
             COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, 
@@ -1498,44 +1773,35 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
         prop->value->metatype = type->attachedPropertiesType();
     } else {
         // Setup regular property data
-        QMetaProperty p;
-
-        if (prop->isDefault) {
-            p = QDeclarativeMetaType::defaultProperty(metaObject);
-
-            if (p.name()) {
-                prop->index = p.propertyIndex();
-                prop->name = p.name();
-            }
-
-        } else {
-            bool notInRevision = false;
-            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(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(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(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
-                }
-            }
-
-            if (prop->index != -1) {
-                p = metaObject->property(prop->index);
-                Q_ASSERT(p.name());
+        bool notInRevision = false;
+        QDeclarativePropertyData *d =
+            prop->name().isEmpty()?0:property(obj, prop->name(), &notInRevision);
 
-                if (!p.isScriptable()) {
-                    prop->index = -1;
-                    p = QMetaProperty();
-                }
+        if (d == 0 && 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().toString()).arg(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().toString()));
             }
+        } else if (d) {
+            prop->index = d->coreIndex;
+            prop->core = *d;
+        } else if (prop->isDefault) {
+            QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
+            QDeclarativePropertyData defaultPropertyData;
+            defaultPropertyData.load(p, engine);
+            if (p.name())
+                prop->setName(QLatin1String(p.name()));
+            prop->core = defaultPropertyData;
+            prop->index = prop->core.coreIndex;
         }
 
         // We can't error here as the "id" property does not require a
         // successful index resolution
-        if (p.name()
-            prop->type = p.userType();
+        if (prop->index != -1
+            prop->type = prop->core.propType;
 
         // Check if this is an alias
         if (prop->index != -1 && 
@@ -1552,17 +1818,17 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
             prop->parent->setBindingBit(prop->index);
     }
 
-    if (!prop->isDefault && prop->name == "id" && !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));
 
@@ -1571,14 +1837,14 @@ 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(QString::fromUtf8(prop->name)));
+            COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString()));
         }
 
     } else if (prop->value) {
 
         COMPILE_CHECK(buildGroupedProperty(prop, obj, ctxt));
 
-    } else if (enginePrivate->isList(prop->type)) {
+    } else if (prop->core.isQList()) {
 
         COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
 
@@ -1596,22 +1862,22 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
 }
 
 bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
-                                                    QDeclarativeParser::Property *nsProp, 
-                                                    QDeclarativeParser::Object *obj, 
+                                                    QDeclarativeScript::Property *nsProp, 
+                                                    QDeclarativeScript::Object *obj, 
                                                     const BindingContext &ctxt)
 {
     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, &type, 0, 0, 0);
+        unit->imports().resolveType(ns, prop->name().toString(), &type, 0, 0, 0);
 
         if (!type || !type->attachedPropertiesType()) 
             COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1629,42 +1895,38 @@ bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespac
     return true;
 }
 
-void QDeclarativeCompiler::genValueProperty(QDeclarativeParser::Property *prop,
-                                   QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genValueProperty(QDeclarativeScript::Property *prop,
+                                   QDeclarativeScript::Object *obj)
 {
-    if (enginePrivate->isList(prop->type)) {
+    if (prop->core.isQList()) {
         genListProperty(prop, obj);
     } else {
         genPropertyAssignment(prop, obj);
     }
 }
 
-void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
-                                  QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genListProperty(QDeclarativeScript::Property *prop,
+                                  QDeclarativeScript::Object *obj)
 {
     int listType = enginePrivate->listType(prop->type);
 
-    QDeclarativeInstruction fetch;
-    fetch.setType(QDeclarativeInstruction::FetchQList);
-    fetch.fetchQmlList.property = prop->index;
+    Instruction::FetchQList fetch;
+    fetch.property = prop->index;
     bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
-    fetch.fetchQmlList.type = listType;
+    fetch.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) {
 
             genObject(v->object);
             if (listTypeIsInterface) {
-                QDeclarativeInstruction assign;
-                assign.setType(QDeclarativeInstruction::AssignObjectList);
-                assign.assignObjectList.line = prop->location.start.line;
+                Instruction::AssignObjectList assign;
+                assign.line = prop->location.start.line;
                 output->addInstruction(assign);
             } else {
-                QDeclarativeInstruction store;
-                store.setType(QDeclarativeInstruction::StoreObjectQList);
+                Instruction::StoreObjectQList store;
                 output->addInstruction(store);
             }
 
@@ -1676,17 +1938,15 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
 
     }
 
-    QDeclarativeInstruction pop;
-    pop.setType(QDeclarativeInstruction::PopQList);
+    Instruction::PopQList pop;
     output->addInstruction(pop);
 }
 
-void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *prop,
-                                        QDeclarativeParser::Object *obj,
-                                        QDeclarativeParser::Property *valueTypeProperty)
+void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeScript::Property *prop,
+                                        QDeclarativeScript::Object *obj,
+                                        QDeclarativeScript::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 ||
@@ -1698,26 +1958,31 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
 
             if (QDeclarativeMetaType::isInterface(prop->type)) {
 
-                QDeclarativeInstruction store;
-                store.setType(QDeclarativeInstruction::StoreInterface);
-                store.storeObject.line = v->object->location.start.line;
-                store.storeObject.propertyIndex = prop->index;
+                Instruction::StoreInterface store;
+                store.line = v->object->location.start.line;
+                store.propertyIndex = prop->index;
                 output->addInstruction(store);
 
-            } else if (prop->type == -1) {
+            } else if (prop->type == QMetaType::QVariant) {
+
+                if (prop->core.isVMEProperty()) {
+                    Instruction::StoreVarObject store;
+                    store.line = v->object->location.start.line;
+                    store.propertyIndex = prop->index;
+                    output->addInstruction(store);
+                } else {
+                    Instruction::StoreVariantObject store;
+                    store.line = v->object->location.start.line;
+                    store.propertyIndex = prop->index;
+                    output->addInstruction(store);
+                }
 
-                QDeclarativeInstruction store;
-                store.setType(QDeclarativeInstruction::StoreVariantObject);
-                store.storeObject.line = v->object->location.start.line;
-                store.storeObject.propertyIndex = prop->index;
-                output->addInstruction(store);
 
             } else {
 
-                QDeclarativeInstruction store;
-                store.setType(QDeclarativeInstruction::StoreObject);
-                store.storeObject.line = v->object->location.start.line;
-                store.storeObject.propertyIndex = prop->index;
+                Instruction::StoreObject store;
+                store.line = v->object->location.start.line;
+                store.propertyIndex = prop->index;
                 output->addInstruction(store);
 
             }
@@ -1727,16 +1992,13 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
 
         } else if (v->type == Value::Literal) {
 
-            QMetaProperty mp = obj->metaObject()->property(prop->index);
-            genLiteralAssignment(mp, v);
+            genLiteralAssignment(prop, v);
 
         }
 
     }
 
-    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);
@@ -1744,56 +2006,54 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
         if (v->type == Value::ValueSource) {
             genObject(v->object);
 
-            QDeclarativeInstruction store;
-            store.setType(QDeclarativeInstruction::StoreValueSource);
+            Instruction::StoreValueSource store;
             if (valueTypeProperty) {
-                store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty);
-                store.assignValueSource.owner = 1;
+                store.property = genValueTypeData(prop, valueTypeProperty);
+                store.owner = 1;
             } else {
-                store.assignValueSource.property = genPropertyData(prop);
-                store.assignValueSource.owner = 0;
+                store.property = prop->core;
+                store.owner = 0;
             }
             QDeclarativeType *valueType = toQmlType(v->object);
-            store.assignValueSource.castValue = valueType->propertyValueSourceCast();
+            store.castValue = valueType->propertyValueSourceCast();
             output->addInstruction(store);
 
         } else if (v->type == Value::ValueInterceptor) {
             genObject(v->object);
 
-            QDeclarativeInstruction store;
-            store.setType(QDeclarativeInstruction::StoreValueInterceptor);
+            Instruction::StoreValueInterceptor store;
             if (valueTypeProperty) {
-                store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty);
-                store.assignValueInterceptor.owner = 1;
+                store.property = genValueTypeData(prop, valueTypeProperty);
+                store.owner = 1;
             } else {
-                store.assignValueInterceptor.property = genPropertyData(prop);
-                store.assignValueInterceptor.owner = 0;
+                store.property = prop->core;
+                store.owner = 0;
             }
             QDeclarativeType *valueType = toQmlType(v->object);
-            store.assignValueInterceptor.castValue = valueType->propertyValueInterceptorCast();
+            store.castValue = valueType->propertyValueInterceptorCast();
             output->addInstruction(store);
         }
 
     }
 }
 
-bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
-                                  QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::buildIdProperty(QDeclarativeScript::Property *prop,
+                                  QDeclarativeScript::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);
+    QDeclarativeScript::Value *idValue = prop->values.first();
     QString val = idValue->primitive();
 
     COMPILE_CHECK(checkValidId(idValue, val));
 
-    if (compileState.ids.contains(val))
+    if (compileState->ids.value(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);
@@ -1801,35 +2061,39 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
     return true;
 }
 
-void QDeclarativeCompiler::addId(const QString &id, QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::addId(const QString &id, QDeclarativeScript::Object *obj)
 {
-    Q_ASSERT(!compileState.ids.contains(id));
+    Q_UNUSED(id);
+    Q_ASSERT(!compileState->ids.value(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.append(obj);
 }
 
-void QDeclarativeCompiler::addBindingReference(const BindingReference &ref)
+void QDeclarativeCompiler::addBindingReference(JSBindingReference *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->totalBindingsCount++;
+    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
-QDeclarativeCompiler::componentState(QDeclarativeParser::Object *obj)
+QDeclarativeCompilerTypes::ComponentCompileState *
+QDeclarativeCompiler::componentState(QDeclarativeScript::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,
@@ -1837,17 +2101,21 @@ QDeclarativeCompiler::componentState(QDeclarativeParser::Object *obj)
 //    GridView.row: 10
 // }
 // GridView is an attached property object.
-bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeParser::Property *prop,
-                                        QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeScript::Property *prop,
+                                        QDeclarativeScript::Object *obj,
                                         const BindingContext &ctxt)
 {
     Q_ASSERT(prop->value);
     Q_ASSERT(prop->index != -1); // This is set in buildProperty()
 
+    compileState->objectDepth.push();
+
     obj->addAttachedProperty(prop);
 
     COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
 
+    compileState->objectDepth.pop();
+
     return true;
 }
 
@@ -1858,32 +2126,33 @@ bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeParser::Property *p
 //     font.family: "Helvetica"
 // }
 // font is a nested property.  pointSize and family are not.
-bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *prop,
-                                                QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeScript::Property *prop,
+                                                QDeclarativeScript::Object *obj,
                                                 const BindingContext &ctxt)
 {
     Q_ASSERT(prop->type != 0);
     Q_ASSERT(prop->index != -1);
 
     if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
-        if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
+        if (prop->type >= 0 && 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(QString::fromUtf8(prop->name)));
+            if (!prop->core.isWritable() && !prop->isReadOnlyDeclaration) {
+                COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
             }
 
 
             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],
@@ -1899,44 +2168,50 @@ 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);
 
+        compileState->objectDepth.push();
+
         COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
+
+        compileState->objectDepth.pop();
     }
 
     return true;
 }
 
 bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
-                                                  QDeclarativeParser::Object *obj,
-                                                  QDeclarativeParser::Object *baseObj,
+                                                  QDeclarativeScript::Object *obj,
+                                                  QDeclarativeScript::Object *baseObj,
                                                   const BindingContext &ctxt)
 {
+    compileState->objectDepth.push();
+
     if (obj->defaultProperty)
         COMPILE_EXCEPTION(obj, tr("Invalid property use"));
     obj->metatype = type->metaObject();
 
-    foreach (Property *prop, obj->properties) {
-        int idx = type->metaObject()->indexOfProperty(prop->name.constData());
-        if (idx == -1)
-            COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
-        QMetaProperty p = type->metaObject()->property(idx);
-        if (!p.isScriptable())
-            COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
-        prop->index = idx;
-        prop->type = p.userType();
+    for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+
+        QDeclarativePropertyData *d = property(obj, prop->name());
+        if (d == 0) 
+            COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString()));
+
+        prop->index = d->coreIndex;
+        prop->type = d->propType;
+        prop->core = *d;
         prop->isValueTypeSubProperty = true;
 
         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()) {
+            QDeclarativeScript::Value *value = prop->values.first();
 
             if (value->object) {
                 COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
@@ -1945,27 +2220,29 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
 
                 //optimization for <Type>.<EnumValue> enum assignments
                 bool isEnumAssignment = false;
-                COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment));
+
+                if (prop->core.isEnum()) 
+                    COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, value, &isEnumAssignment));
+
                 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++;
+                    JSBindingReference *reference = pool->New<JSBindingReference>();
+                    reference->expression = value->value;
+                    reference->property = prop;
+                    reference->value = value;
+                    reference->bindingContext = ctxt;
+                    reference->bindingContext.owner++;
                     addBindingReference(reference);
                     value->type = Value::PropertyBinding;
                 }
             } else  {
-                COMPILE_CHECK(testLiteralAssignment(p, value));
+                COMPILE_CHECK(testLiteralAssignment(prop, value));
                 value->type = Value::Literal;
             }
         }
 
-        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)); 
@@ -1974,17 +2251,21 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
         obj->addValueProperty(prop);
     }
 
+    compileState->objectDepth.pop();
+
     return true;
 }
 
 // Build assignments to QML lists.  QML lists are properties of type
 // QDeclarativeListProperty<T>.  List properties can accept a list of 
 // objects, or a single binding.
-bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
-                                             QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildListProperty(QDeclarativeScript::Property *prop,
+                                             QDeclarativeScript::Object *obj,
                                              const BindingContext &ctxt)
 {
-    Q_ASSERT(enginePrivate->isList(prop->type));
+    Q_ASSERT(prop->core.isQList());
+
+    compileState->listDepth.push();
 
     int t = prop->type;
 
@@ -1994,8 +2275,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));
@@ -2020,37 +2300,39 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
         }
     }
 
+    compileState->listDepth.pop();
+
     return true;
 }
 
 // Compiles an assignment to a QDeclarativeScriptString property
-bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeParser::Property *prop,
-                                            QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeScript::Property *prop,
+                                            QDeclarativeScript::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;
 }
 
 // Compile regular property assignments of the form "property: <value>"
-bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property *prop,
-                                          QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeScript::Property *prop,
+                                          QDeclarativeScript::Object *obj,
                                           const BindingContext &ctxt)
 {
     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));
@@ -2062,9 +2344,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));
     }
@@ -2073,16 +2353,16 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
 }
 
 // Compile assigning a single object instance to a regular property
-bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
-                                                         QDeclarativeParser::Object *obj,
-                                                         QDeclarativeParser::Value *v,
+bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeScript::Property *prop,
+                                                         QDeclarativeScript::Object *obj,
+                                                         QDeclarativeScript::Value *v,
                                                          const BindingContext &ctxt)
 {
     Q_ASSERT(prop->index != -1);
     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(QString::fromUtf8(prop->name)));
+    if (!prop->core.isWritable() && !prop->isReadOnlyDeclaration)
+        COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
 
     if (QDeclarativeMetaType::isInterface(prop->type)) {
 
@@ -2091,7 +2371,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
 
         v->type = Value::CreatedObject;
 
-    } else if (prop->type == -1) {
+    } else if (prop->type == QMetaType::QVariant) {
 
         // Assigning an object to a QVariant
         COMPILE_CHECK(buildObject(v->object, ctxt));
@@ -2128,13 +2408,13 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
             v->type = Value::CreatedObject;
         } else if (propertyMetaObject == &QDeclarativeComponent::staticMetaObject) {
             // Automatic "Component" insertion
-            QDeclarativeParser::Object *root = v->object;
-            QDeclarativeParser::Object *component = new QDeclarativeParser::Object;
+            QDeclarativeScript::Object *root = v->object;
+            QDeclarativeScript::Object *component = pool->New<Object>();
             component->type = componentTypeRef();
-            component->typeName = "Qt/Component";
+            component->typeName = QStringLiteral("Qt/Component");
             component->metatype = &QDeclarativeComponent::staticMetaObject;
             component->location = root->location;
-            QDeclarativeParser::Value *componentValue = new QDeclarativeParser::Value;
+            QDeclarativeScript::Value *componentValue = pool->New<Value>();
             componentValue->object = root;
             component->getDefaultProperty()->addValue(componentValue);
             v->object = component;
@@ -2153,17 +2433,19 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
 //     Item {
 //         NumberAnimation on x { }
 //     }
-bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
-                                                     QDeclarativeParser::Object *obj,
-                                                     QDeclarativeParser::Object *baseObj,
-                                                     QDeclarativeParser::Value *v,
+bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeScript::Property *prop,
+                                                     QDeclarativeScript::Object *obj,
+                                                     QDeclarativeScript::Object *baseObj,
+                                                     QDeclarativeScript::Value *v,
                                                      const BindingContext &ctxt)
 {
     Q_ASSERT(prop->index != -1);
     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(QString::fromUtf8(prop->name)));
+    Q_UNUSED(obj);
+
+    if (!prop->core.isWritable())
+        COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
 
 
     // Normally buildObject() will set this up, but we need the static
@@ -2190,37 +2472,41 @@ 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(QString::fromUtf8(prop->name.constData())));
+        COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(v->object->typeName).arg(prop->name().toString()));
     }
 
     return true;
 }
 
 // Compile assigning a literal or binding to a regular property
-bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
-                                                 QDeclarativeParser::Object *obj,
-                                                 QDeclarativeParser::Value *v,
-                                                 const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeScript::Property *prop,
+                                                          QDeclarativeScript::Object *obj,
+                                                          QDeclarativeScript::Value *v,
+                                                          const BindingContext &ctxt)
 {
     Q_ASSERT(prop->index != -1);
 
     if (v->value.isScript()) {
 
         //optimization for <Type>.<EnumValue> enum assignments
-        bool isEnumAssignment = false;
-        COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment));
-        if (isEnumAssignment) {
-            v->type = Value::Literal;
-            return true;
+        if (prop->core.isEnum()) {
+            bool isEnumAssignment = false;
+            COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, v, &isEnumAssignment));
+            if (isEnumAssignment) {
+                v->type = Value::Literal;
+                return true;
+            }
         }
 
-        COMPILE_CHECK(buildBinding(v, prop, ctxt));
+        // Test for other binding optimizations
+        if (!buildLiteralBinding(v, prop, ctxt))
+            COMPILE_CHECK(buildBinding(v, prop, ctxt));
 
         v->type = Value::PropertyBinding;
 
     } else {
 
-        COMPILE_CHECK(testLiteralAssignment(obj->metaObject()->property(prop->index), v));
+        COMPILE_CHECK(testLiteralAssignment(prop, v));
 
         v->type = Value::Literal;
     }
@@ -2228,17 +2514,19 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr
     return true;
 }
 
-bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop,
-                                              QDeclarativeParser::Object *obj,
-                                              QDeclarativeParser::Value *v,
-                                              bool *isAssignment)
+bool QDeclarativeCompiler::testQualifiedEnumAssignment(QDeclarativeScript::Property *prop,
+                                                       QDeclarativeScript::Object *obj,
+                                                       QDeclarativeScript::Value *v,
+                                                       bool *isAssignment)
 {
     *isAssignment = false;
-    if (!prop.isEnumType())
+    if (!prop->core.isEnum())
         return true;
 
-    if (!prop.isWritable())
-        COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
+    QMetaProperty mprop = obj->metaObject()->property(prop->index);
+
+    if (!prop->core.isWritable() && !prop->isReadOnlyDeclaration)
+        COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
 
     QString string = v->value.asString();
     if (!string.at(0).isUpper())
@@ -2250,10 +2538,10 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
 
     QString typeName = parts.at(0);
     QDeclarativeType *type = 0;
-    unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
+    unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
 
     //handle enums on value types (where obj->typeName is empty)
-    QByteArray objTypeName = obj->typeName;
+    QString objTypeName = obj->typeName;
     if (objTypeName.isEmpty()) {
         QDeclarativeType *objType = toQmlType(obj);
         if (objType)
@@ -2264,61 +2552,71 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
         return true;
 
     QString enumValue = parts.at(1);
-    int value = -1;
+    int value;
+    bool ok;
 
     if (objTypeName == type->qmlTypeName()) {
         // When these two match, we can short cut the search
-        if (prop.isFlagType()) {
-            value = prop.enumerator().keysToValue(enumValue.toUtf8().constData());
+        if (mprop.isFlagType()) {
+            value = mprop.enumerator().keysToValue(enumValue.toUtf8().constData(), &ok);
         } else {
-            value = prop.enumerator().keyToValue(enumValue.toUtf8().constData());
+            value = mprop.enumerator().keyToValue(enumValue.toUtf8().constData(), &ok);
         }
     } else {
         // Otherwise we have to search the whole type
         // This matches the logic in QV8TypeWrapper
         QByteArray enumName = enumValue.toUtf8();
         const QMetaObject *metaObject = type->baseMetaObject();
-        for (int ii = metaObject->enumeratorCount() - 1; value == -1 && ii >= 0; --ii) {
+        ok = false;
+        for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
             QMetaEnum e = metaObject->enumerator(ii);
-            value = e.keyToValue(enumName.constData());
+            value = e.keyToValue(enumName.constData(), &ok);
         }
     }
 
-    if (value == -1)
+    if (!ok)
         return true;
 
     v->type = Value::Literal;
-    v->value = QDeclarativeParser::Variant((double)value);
+    v->value = QDeclarativeScript::Variant((double)value);
     *isAssignment = true;
 
     return true;
 }
 
+struct StaticQtMetaObject : public QObject
+{
+    static const QMetaObject *get()
+        { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
+};
+
 // Similar logic to above, but not knowing target property.
 int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
 {
     int dot = script.indexOf('.');
     if (dot > 0) {
+        const QByteArray &scope = script.left(dot);
         QDeclarativeType *type = 0;
-        unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
-        if (!type)
+        unit->imports().resolveType(QString::fromUtf8(script.left(dot)), &type, 0, 0, 0, 0);
+        if (!type && scope != "Qt")
             return -1;
-        const QMetaObject *mo = type->metaObject();
+        const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
         const char *key = script.constData() + dot+1;
         int i = mo->enumeratorCount();
         while (i--) {
-            int v = mo->enumerator(i).keyToValue(key);
-            if (v >= 0)
+            bool ok;
+            int v = mo->enumerator(i).keyToValue(key, &ok);
+            if (ok)
                 return v;
         }
     }
     return -1;
 }
 
-const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
+const QMetaObject *QDeclarativeCompiler::resolveType(const QString& name) const
 {
     QDeclarativeType *qmltype = 0;
-    if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0)) 
+    if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
         return 0;
     if (!qmltype)
         return 0;
@@ -2327,27 +2625,36 @@ const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) con
 
 // similar to logic of completeComponentBuild, but also sticks data
 // into primitives at the end
-int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteArray& name)
+int QDeclarativeCompiler::rewriteBinding(const QDeclarativeScript::Variant& value, const QString& name)
 {
     QDeclarativeRewrite::RewriteBinding rewriteBinding;
-    rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
+    rewriteBinding.setName(QLatin1Char('$') + name.mid(name.lastIndexOf(QLatin1Char('.')) + 1));
 
-    QString rewrite = rewriteBinding(expression, 0, 0);
+    QString rewrite = rewriteBinding(value.asAST(), value.asScript(), 0);
 
     return output->indexForString(rewrite);
 }
 
+QString QDeclarativeCompiler::rewriteSignalHandler(const QString &handler, const QString &name)
+{
+    QDeclarativeRewrite::RewriteSignalHandler rewriteSignalHandler;
+    return rewriteSignalHandler(handler, name);
+}
+
 // Ensures that the dynamic meta specification on obj is valid
-bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeScript::Object *obj)
 {
-    QSet<QByteArray> propNames;
-    QSet<QByteArray> methodNames;
     bool seenDefaultProperty = false;
 
+    // We use a coarse grain, 31 bit hash to check if there are duplicates.
+    // Calculating the hash for the names is not a waste as we have to test
+    // them against the illegalNames set anyway.
+    QHashField propNames;
+    QHashField methodNames;
+
     // Check properties
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const QDeclarativeParser::Object::DynamicProperty &prop =
-            obj->dynamicProperties.at(ii);
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+        const QDeclarativeScript::Object::DynamicProperty &prop = *p;
 
         if (prop.isDefaultProperty) {
             if (seenDefaultProperty)
@@ -2355,77 +2662,103 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
             seenDefaultProperty = true;
         }
 
-        if (propNames.contains(prop.name))
-            COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
-
-        QString propName = QString::fromUtf8(prop.name);
-        if (propName.at(0).isUpper())
-            COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
+        if (propNames.testAndSet(prop.name.hash())) {
+            for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p; 
+                 p2 = obj->dynamicProperties.next(p2)) {
+                if (p2->name == prop.name) {
+                    COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                               prop.nameLocation.column,
+                                               tr("Duplicate property name"));
+                }
+            }
+        }
 
-        if (enginePrivate->v8engine.illegalNames().contains(propName))
-            COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
+        if (prop.name.at(0).isUpper()) {
+            COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                       prop.nameLocation.column,
+                                       tr("Property names cannot begin with an upper case letter"));
+        }
 
-        propNames.insert(prop.name);
+        if (enginePrivate->v8engine()->illegalNames().contains(prop.name)) {
+            COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
+                                       prop.nameLocation.column,
+                                       tr("Illegal property name"));
+        }
     }
 
-    for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
-        QByteArray name = obj->dynamicSignals.at(ii).name;
-        if (methodNames.contains(name))
-            COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
-        QString nameStr = QString::fromUtf8(name);
-        if (nameStr.at(0).isUpper())
-            COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
-        if (enginePrivate->v8engine.illegalNames().contains(nameStr))
-            COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
-        methodNames.insert(name);
+    for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+        const QDeclarativeScript::Object::DynamicSignal &currSig = *s;
+
+        if (methodNames.testAndSet(currSig.name.hash())) {
+            for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2 != s;
+                 s2 = obj->dynamicSignals.next(s2)) {
+                if (s2->name == currSig.name)
+                    COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name"));
+            }
+        }
+
+        if (currSig.name.at(0).isUpper())
+            COMPILE_EXCEPTION(&currSig, tr("Signal names cannot begin with an upper case letter"));
+        if (enginePrivate->v8engine()->illegalNames().contains(currSig.name))
+            COMPILE_EXCEPTION(&currSig, tr("Illegal signal name"));
     }
-    for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
-        QByteArray name = obj->dynamicSlots.at(ii).name;
-        if (methodNames.contains(name))
-            COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
-        QString nameStr = QString::fromUtf8(name);
-        if (nameStr.at(0).isUpper())
-            COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
-        if (enginePrivate->v8engine.illegalNames().contains(nameStr))
-            COMPILE_EXCEPTION(obj, tr("Illegal method name"));
-        methodNames.insert(name);
+
+    for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+        const QDeclarativeScript::Object::DynamicSlot &currSlot = *s;
+
+        if (methodNames.testAndSet(currSlot.name.hash())) {
+            for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2;
+                 s2 = obj->dynamicSignals.next(s2)) {
+                if (s2->name == currSlot.name)
+                    COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+            }
+            for (Object::DynamicSlot *s2 = obj->dynamicSlots.first(); s2 != s;
+                 s2 = obj->dynamicSlots.next(s2)) {
+                if (s2->name == currSlot.name)
+                    COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+            }
+        }
+
+        if (currSlot.name.at(0).isUpper())
+            COMPILE_EXCEPTION(&currSlot, tr("Method names cannot begin with an upper case letter"));
+        if (enginePrivate->v8engine()->illegalNames().contains(currSlot.name))
+            COMPILE_EXCEPTION(&currSlot, tr("Illegal method name"));
     }
 
     return true;
 }
 
-bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeScript::Object *obj)
 {
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p;
+         p = obj->dynamicProperties.next(p)) {
 
-        if (!p.defaultValue || p.type == Object::DynamicProperty::Alias)
+        if (!p->defaultValue || p->type == Object::DynamicProperty::Alias)
             continue;
 
         Property *property = 0;
-        if (p.isDefaultProperty) {
+        if (p->isDefaultProperty) {
             property = obj->getDefaultProperty();
         } else {
-            property = obj->getProperty(p.name);
+            property = obj->getProperty(p->name);
             if (!property->values.isEmpty()) 
                 COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
         }
 
+        if (p->isReadOnly)
+            property->isReadOnlyDeclaration = true;
+
         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;
 }
 
 Q_GLOBAL_STATIC(QAtomicInt, classIndexCounter)
 
-bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode)
+bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, DynamicMetaMode mode)
 {
     Q_ASSERT(obj);
     Q_ASSERT(obj->metatype);
@@ -2436,61 +2769,125 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
         obj->dynamicSlots.isEmpty())
         return true;
 
-    QByteArray dynamicData(sizeof(QDeclarativeVMEMetaData), (char)0);
+    bool resolveAlias = (mode == ResolveAliases);
+
+    const Object::DynamicProperty *defaultProperty = 0;
+    int aliasCount = 0;
+    int varPropCount = 0;
+    int totalPropCount = 0;
+    int firstPropertyVarIndex = 0;
+
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+
+        if (p->type == Object::DynamicProperty::Alias)
+            aliasCount++;
+        if (p->type == Object::DynamicProperty::Var)
+            varPropCount++;
+
+        if (p->isDefaultProperty && 
+            (resolveAlias || p->type != Object::DynamicProperty::Alias))
+            defaultProperty = p;
+
+        if (!resolveAlias) {
+            // No point doing this for both the alias and non alias cases
+            QDeclarativePropertyData *d = property(obj, p->name);
+            if (d && d->isFinal())
+                COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
+        }
+    }
+
+    bool buildData = resolveAlias || aliasCount == 0;
+
+    QByteArray dynamicData;
+    if (buildData) {
+        typedef QDeclarativeVMEMetaData VMD;
+
+        dynamicData = QByteArray(sizeof(QDeclarativeVMEMetaData) +
+                                 (obj->dynamicProperties.count() - aliasCount) * sizeof(VMD::PropertyData) +
+                                 obj->dynamicSlots.count() * sizeof(VMD::MethodData) +
+                                 aliasCount * sizeof(VMD::AliasData), 0);
+    }
+
+    int uniqueClassId = classIndexCounter()->fetchAndAddRelaxed(1);
 
     QByteArray newClassName = obj->metatype->className();
     newClassName.append("_QML_");
-    int idx = classIndexCounter()->fetchAndAddRelaxed(1);
-    newClassName.append(QByteArray::number(idx));
-    if (compileState.root == obj && !compileState.nested) {
+    newClassName.append(QByteArray::number(uniqueClassId));
+
+    if (compileState->root == obj && !compileState->nested) {
         QString path = output->url.path();
         int lastSlash = path.lastIndexOf(QLatin1Char('/'));
         if (lastSlash > -1) {
             QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
             if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
-                newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(idx);
-        }
-    }
-
-    QMetaObjectBuilder builder;
-    builder.setClassName(newClassName);
-    builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
-
-    bool hasAlias = false;
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+                newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(uniqueClassId);
+        }
+    }
+
+    QFastMetaBuilder builder;
+    QFastMetaBuilder::StringRef classNameRef = builder.init(newClassName.length(), 
+            obj->dynamicProperties.count() - (resolveAlias?0:aliasCount),
+            obj->dynamicSlots.count(),
+            obj->dynamicSignals.count() + obj->dynamicProperties.count(),
+            defaultProperty?1:0);
+
+    struct TypeData {
+        Object::DynamicProperty::Type dtype;
+        int metaType;
+        const char *cppType;
+    } builtinTypes[] = {
+        { Object::DynamicProperty::Var, QMetaType::QVariant, "QVariant" },
+        { Object::DynamicProperty::Variant, QMetaType::QVariant, "QVariant" },
+        { Object::DynamicProperty::Int, QMetaType::Int, "int" },
+        { Object::DynamicProperty::Bool, QMetaType::Bool, "bool" },
+        { Object::DynamicProperty::Real, QMetaType::Double, "double" },
+        { Object::DynamicProperty::String, QMetaType::QString, "QString" },
+        { Object::DynamicProperty::Url, QMetaType::QUrl, "QUrl" },
+        { Object::DynamicProperty::Color, QMetaType::QColor, "QColor" },
+        { Object::DynamicProperty::Time, QMetaType::QTime, "QTime" },
+        { Object::DynamicProperty::Date, QMetaType::QDate, "QDate" },
+        { Object::DynamicProperty::DateTime, QMetaType::QDateTime, "QDateTime" },
+    };
+    static const int builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
+    QFastMetaBuilder::StringRef typeRefs[builtinTypeCount]; 
+
+    // Reserve dynamic properties
+    if (obj->dynamicProperties.count()) {
+        typedef QDeclarativeVMEMetaData VMD;
+
+        int effectivePropertyIndex = 0;
+        for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+
+            // Reserve space for name
+            p->nameRef = builder.newString(p->name.utf8length());
+
+            int propertyType = 0;
+            bool readonly = false;
+            QFastMetaBuilder::StringRef typeRef;
+
+            if (p->type == Object::DynamicProperty::Alias) {
+                continue;
+            } else if (p->type < builtinTypeCount) {
+                Q_ASSERT(builtinTypes[p->type].dtype == p->type);
+                propertyType = builtinTypes[p->type].metaType;
+                if (typeRefs[p->type].isEmpty()) 
+                    typeRefs[p->type] = builder.newString(strlen(builtinTypes[p->type].cppType));
+                typeRef = typeRefs[p->type];
 
-        int propIdx = obj->metaObject()->indexOfProperty(p.name.constData());
-        if (-1 != propIdx) {
-            QMetaProperty prop = obj->metaObject()->property(propIdx);
-            if (prop.isFinal())
-                COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
-        }
+            } else {
+                Q_ASSERT(p->type == Object::DynamicProperty::CustomList ||
+                         p->type == Object::DynamicProperty::Custom);
 
-        if (p.isDefaultProperty &&
-            (p.type != Object::DynamicProperty::Alias ||
-             mode == ResolveAliases))
-            builder.addClassInfo("DefaultProperty", p.name);
+                // XXX don't double resolve this in the case of an alias run
 
-        QByteArray type;
-        int propertyType = 0;
-        bool readonly = false;
-        switch(p.type) {
-        case Object::DynamicProperty::Alias:
-            hasAlias = true;
-            continue;
-            break;
-        case Object::DynamicProperty::CustomList:
-        case Object::DynamicProperty::Custom:
-            {
                 QByteArray customTypeName;
                 QDeclarativeType *qmltype = 0;
-                QUrl url;
-                if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0)) 
-                    COMPILE_EXCEPTION(&p, tr("Invalid property type"));
+                QString url;
+                if (!unit->imports().resolveType(p->customType.toString(), &qmltype, &url, 0, 0, 0))
+                    COMPILE_EXCEPTION(p, tr("Invalid property type"));
 
                 if (!qmltype) {
-                    QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
+                    QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(QUrl(url));
                     Q_ASSERT(tdata);
                     Q_ASSERT(tdata->isComplete());
 
@@ -2502,146 +2899,250 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
                     customTypeName = qmltype->typeName();
                 }
 
-                if (p.type == Object::DynamicProperty::Custom) {
-                    type = customTypeName + '*';
+                if (p->type == Object::DynamicProperty::Custom) {
+                    customTypeName += '*';
                     propertyType = QMetaType::QObjectStar;
                 } else {
                     readonly = true;
-                    type = "QDeclarativeListProperty<";
-                    type.append(customTypeName);
-                    type.append(">");
+                    customTypeName = QByteArray("QDeclarativeListProperty<") + customTypeName + QByteArray(">");
                     propertyType = qMetaTypeId<QDeclarativeListProperty<QObject> >();
                 }
+
+                p->resolvedCustomTypeName = pool->NewByteArray(customTypeName);
+                p->typeRef = builder.newString(customTypeName.length());
+                typeRef = p->typeRef;
+            }
+
+            if (p->type == Object::DynamicProperty::Var)
+                continue;
+
+            if (p->isReadOnly)
+                readonly = true;
+
+            if (buildData) {
+                VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+                vmd->propertyCount++;
+                (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType;
+            }
+
+            if (p->type < builtinTypeCount)
+                builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)propertyType, 
+                                    readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, 
+                                    effectivePropertyIndex);
+            else 
+                builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, 
+                                    readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, 
+                                    effectivePropertyIndex);
+
+            p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+            builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
+
+            effectivePropertyIndex++;
+        }
+
+        if (varPropCount) {
+            VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+            if (buildData)
+                vmd->varPropertyCount = varPropCount;
+            firstPropertyVarIndex = effectivePropertyIndex;
+            totalPropCount = varPropCount + effectivePropertyIndex;
+            for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+                if (p->type == Object::DynamicProperty::Var) {
+                    QFastMetaBuilder::StringRef typeRef = typeRefs[p->type];
+                    if (buildData) {
+                        vmd->propertyCount++;
+                        (vmd->propertyData() + effectivePropertyIndex)->propertyType = QMetaType::QVariant;
+                    }
+
+                    builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef,
+                                        QMetaType::QVariant,
+                                        p->isReadOnly?QFastMetaBuilder::None:QFastMetaBuilder::Writable,
+                                        effectivePropertyIndex);
+
+                    p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+                    builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
+
+                    effectivePropertyIndex++;
+                }
+            }
+        }
+        
+        if (aliasCount) {
+            int aliasIndex = 0;
+            for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+                if (p->type == Object::DynamicProperty::Alias) {
+                    if (resolveAlias) {
+                        Q_ASSERT(buildData);
+                        ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
+                        COMPILE_CHECK(compileAlias(builder, dynamicData, obj, effectivePropertyIndex, 
+                                                   aliasIndex, *p));
+                    }
+                    // Even if we aren't resolving the alias, we need a fake signal so that the 
+                    // metaobject remains consistent across the resolve and non-resolve alias runs
+                    p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+                    builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
+                    effectivePropertyIndex++;
+                    aliasIndex++;
+                }
             }
-            break;
-        case Object::DynamicProperty::Variant:
-            propertyType = -1;
-            type = "QVariant";
-            break;
-        case Object::DynamicProperty::Int:
-            propertyType = QVariant::Int;
-            type = "int";
-            break;
-        case Object::DynamicProperty::Bool:
-            propertyType = QVariant::Bool;
-            type = "bool";
-            break;
-        case Object::DynamicProperty::Real:
-            propertyType = QVariant::Double;
-            type = "double";
-            break;
-        case Object::DynamicProperty::String:
-            propertyType = QVariant::String;
-            type = "QString";
-            break;
-        case Object::DynamicProperty::Url:
-            propertyType = QVariant::Url;
-            type = "QUrl";
-            break;
-        case Object::DynamicProperty::Color:
-            propertyType = QVariant::Color;
-            type = "QColor";
-            break;
-        case Object::DynamicProperty::Time:
-            propertyType = QVariant::Time;
-            type = "QTime";
-            break;
-        case Object::DynamicProperty::Date:
-            propertyType = QVariant::Date;
-            type = "QDate";
-            break;
-        case Object::DynamicProperty::DateTime:
-            propertyType = QVariant::DateTime;
-            type = "QDateTime";
-            break;
         }
+    }
+
+    // Reserve default property
+    QFastMetaBuilder::StringRef defPropRef;
+    if (defaultProperty) {
+        defPropRef = builder.newString(strlen("DefaultProperty"));
+        builder.setClassInfo(0, defPropRef, defaultProperty->nameRef);
+    }
+
+    // Reserve dynamic signals
+    int signalIndex = 0;
+    for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+
+        int paramCount = s->parameterNames.count();
+
+        int signatureSize = s->name.utf8length() + 2 /* paren */;
+        int namesSize = 0;
+        if (paramCount) signatureSize += s->parameterTypesLength() + (paramCount - 1) /* commas */;
+        if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1) /* commas */;
 
-        ((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++;
-        QDeclarativeVMEMetaData::PropertyData propertyData = { propertyType };
-        dynamicData.append((char *)&propertyData, sizeof(propertyData));
+        s->signatureRef = builder.newString(signatureSize);
+        if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
 
-        builder.addSignal(p.name + "Changed()");
-        QMetaPropertyBuilder propBuilder = 
-            builder.addProperty(p.name, type, builder.methodCount() - 1);
-        propBuilder.setWritable(!readonly);
+        if (buildData)
+            ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
+        
+        builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->signatureRef, s->parameterNamesRef);
+        ++signalIndex;
     }
 
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+    // Reserve dynamic slots
+    if (obj->dynamicSlots.count()) {
 
-        if (p.type == Object::DynamicProperty::Alias) {
-            if (mode == ResolveAliases) {
-                ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
-                COMPILE_CHECK(compileAlias(builder, dynamicData, obj, p));
-            } else {
-                // Need a fake signal so that the metaobject remains consistent across
-                // the resolve and non-resolve alias runs
-                builder.addSignal(p.name + "Changed()");
+        // Allocate QVariant string
+        if (typeRefs[0].isEmpty()) 
+            typeRefs[0] = builder.newString(strlen(builtinTypes[0].cppType));
+
+        typedef QDeclarativeVMEMetaData VMD;
+
+        int methodIndex = 0;
+        for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+            int paramCount = s->parameterNames.count();
+
+            int signatureSize = s->name.utf8length() + 2 /* paren */;
+            int namesSize = 0; 
+            if (paramCount) signatureSize += (paramCount * strlen("QVariant") + (paramCount - 1));
+            if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); 
+
+            s->signatureRef = builder.newString(signatureSize);
+            if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
+
+            builder.setMethod(methodIndex, s->signatureRef, s->parameterNamesRef, typeRefs[0]);
+
+            if (buildData) {
+                QString funcScript;
+                funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + 
+                        namesSize + 1 /* rparen */ + s->body.length() + 1 /* rparen */);
+                funcScript = QLatin1String("(function ") + s->name.toString() + QLatin1Char('(');
+                for (int jj = 0; jj < paramCount; ++jj) {
+                    if (jj) funcScript.append(QLatin1Char(','));
+                    funcScript.append(QLatin1String(s->parameterNames.at(jj)));
+                }
+                funcScript += QLatin1Char(')') + s->body + QLatin1Char(')');
+
+                VMD::MethodData methodData = { s->parameterNames.count(), 0, 
+                                               funcScript.length(), 
+                                               s->location.start.line };
+
+                VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+                vmd->methodCount++;
+
+                VMD::MethodData &md = *(vmd->methodData() + methodIndex);
+                md = methodData;
+                md.bodyOffset = dynamicData.size();
+
+                dynamicData.append((const char *)funcScript.constData(),
+                                   (funcScript.length() * sizeof(QChar)));
             }
-        }
-    }
 
-    for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
-        const Object::DynamicSignal &s = obj->dynamicSignals.at(ii);
-        QByteArray sig(s.name + '(');
-        for (int jj = 0; jj < s.parameterTypes.count(); ++jj) {
-            if (jj) sig.append(',');
-            sig.append(s.parameterTypes.at(jj));
+            methodIndex++;
         }
-        sig.append(')');
-        QMetaMethodBuilder b = builder.addSignal(sig);
-        b.setParameterNames(s.parameterNames);
-        ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
     }
 
-    QStringList funcScripts;
+    // Now allocate used builtin types
+    for (int ii = 0; ii < builtinTypeCount; ++ii) {
+        if (!typeRefs[ii].isEmpty())
+            typeRefs[ii].load(builtinTypes[ii].cppType);
+    }
 
-    for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
-        Object::DynamicSlot &s = obj->dynamicSlots[ii];
-        QByteArray sig(s.name + '(');
-        QString funcScript(QLatin1String("(function ") + s.name + QLatin1Char('('));
+    // Now allocate properties
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
 
-        for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
-            if (jj) { 
-                sig.append(',');
-                funcScript.append(QLatin1Char(','));
-            }
-            funcScript.append(QLatin1String(s.parameterNames.at(jj)));
-            sig.append("QVariant");
-        }
-        sig.append(')');
-        funcScript.append(QLatin1Char(')'));
-        funcScript.append(s.body);
-        funcScript.append(QLatin1Char(')'));
-        funcScripts << funcScript;
+        char *d = p->changedSignatureRef.data();
+        p->name.writeUtf8(d);
+        strcpy(d + p->name.utf8length(), "Changed()");
 
-        QMetaMethodBuilder b = builder.addSlot(sig);
-        b.setReturnType("QVariant");
-        b.setParameterNames(s.parameterNames);
+        if (p->type == Object::DynamicProperty::Alias && !resolveAlias)
+            continue;
 
-        ((QDeclarativeVMEMetaData *)dynamicData.data())->methodCount++;
-        QDeclarativeVMEMetaData::MethodData methodData =
-             { s.parameterNames.count(), 0, funcScript.length(), s.location.start.line };
+        p->nameRef.load(p->name);
 
-        dynamicData.append((char *)&methodData, sizeof(methodData));
+        if (p->type >= builtinTypeCount) {
+            Q_ASSERT(p->resolvedCustomTypeName);
+            p->typeRef.load(*p->resolvedCustomTypeName);
+        }
     }
 
-    for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
-        const QString &funcScript = funcScripts.at(ii);
-        QDeclarativeVMEMetaData::MethodData *data =
-            ((QDeclarativeVMEMetaData *)dynamicData.data())->methodData() + ii;
+    // Allocate default property if necessary
+    if (defaultProperty) 
+        strcpy(defPropRef.data(), "DefaultProperty");
+
+    // Now allocate signals
+    for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
 
-        data->bodyOffset = dynamicData.size();
+        char *d = s->signatureRef.data();
+        char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+        s->name.writeUtf8(d); d += s->name.utf8length();
+        *d++ = '('; 
+
+        for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
+            if (jj != 0) { *d++ = ','; *d2++ = ','; }
+            strcpy(d, s->parameterTypes.at(jj).constData());
+            d += s->parameterTypes.at(jj).length();
+            s->parameterNames.at(jj).writeUtf8(d2);
+            d2 += s->parameterNames.at(jj).utf8length();
+        }
+        *d++ = ')';
+        *d = 0;
+        if (d2) *d2 = 0;
+    }
 
-        dynamicData.append((const char *)funcScript.constData(),
-                           (funcScript.length() * sizeof(QChar)));
+    // Now allocate methods
+    for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+        char *d = s->signatureRef.data();
+        char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+        s->name.writeUtf8(d); d += s->name.utf8length();
+        *d++ = '('; 
+        for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
+            if (jj != 0) { *d++ = ','; *d2++ = ','; }
+            strcpy(d, "QVariant");
+            d += strlen("QVariant");
+            strcpy(d2, s->parameterNames.at(jj).constData());
+            d2 += s->parameterNames.at(jj).length();
+        }
+        *d++ = ')';
+        *d = 0;
+        if (d2) *d2 = 0;
     }
 
-    obj->metadata = builder.toRelocatableData();
-    builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata);
+    // Now allocate class name
+    classNameRef.load(newClassName);
+
+    obj->metadata = builder.toData();
+    builder.fromData(&obj->extObject, obj->metatype, obj->metadata);
 
-    if (mode == IgnoreAliases && hasAlias)
-        compileState.aliasingObjects << obj;
+    if (mode == IgnoreAliases && aliasCount) 
+        compileState->aliasingObjects.append(obj);
 
     obj->synthdata = dynamicData;
 
@@ -2651,48 +3152,59 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
     }
 
     if (obj->type != -1) {
-        QDeclarativePropertyCache *cache = output->types[obj->type].createPropertyCache(engine)->copy();
-        cache->append(engine, &obj->extObject, QDeclarativePropertyCache::Data::NoFlags,
-                      QDeclarativePropertyCache::Data::IsVMEFunction, 
-                      QDeclarativePropertyCache::Data::IsVMESignal);
+        QDeclarativePropertyCache *superCache = output->types[obj->type].createPropertyCache(engine);
+        QDeclarativePropertyCache *cache =
+            superCache->copyAndAppend(engine, &obj->extObject,
+                                      QDeclarativePropertyData::NoFlags,
+                                      QDeclarativePropertyData::IsVMEFunction,
+                                      QDeclarativePropertyData::IsVMESignal);
+
+        // now we modify the flags appropriately for var properties.
+        int propertyOffset = obj->extObject.propertyOffset();
+        QDeclarativePropertyData *currPropData = 0;
+        for (int pvi = firstPropertyVarIndex; pvi < totalPropCount; ++pvi) {
+            currPropData = cache->property(pvi + propertyOffset);
+            currPropData->setFlags(currPropData->getFlags() | QDeclarativePropertyData::IsVMEProperty);
+        }
+
         obj->synthCache = cache;
     }
 
     return true;
 }
 
-bool QDeclarativeCompiler::checkValidId(QDeclarativeParser::Value *v, const QString &val)
+bool QDeclarativeCompiler::checkValidId(QDeclarativeScript::Value *v, const QString &val)
 {
     if (val.isEmpty()) 
         COMPILE_EXCEPTION(v, tr( "Invalid empty ID"));
 
-    if (val.at(0).isLetter() && !val.at(0).isLower()) 
+    QChar ch = val.at(0);
+    if (ch.isLetter() && !ch.isLower())
         COMPILE_EXCEPTION(v, tr( "IDs cannot start with an uppercase letter"));
 
     QChar u(QLatin1Char('_'));
-    for (int ii = 0; ii < val.count(); ++ii) {
+    if (!ch.isLetter() && ch != u)
+        COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
 
-        if (ii == 0 && !val.at(ii).isLetter() && val.at(ii) != u) {
-            COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
-        } else if (ii != 0 && !val.at(ii).isLetterOrNumber() && val.at(ii) != u)  {
+    for (int ii = 1; ii < val.count(); ++ii) {
+        ch = val.at(ii);
+        if (!ch.isLetterOrNumber() && ch != u)
             COMPILE_EXCEPTION(v, tr( "IDs must contain only letters, numbers, and underscores"));
-        }
-
     }
 
-    if (enginePrivate->v8engine.illegalNames().contains(val))
+    if (enginePrivate->v8engine()->illegalNames().contains(val))
         COMPILE_EXCEPTION(v, tr( "ID illegally masks global JavaScript property"));
 
     return true;
 }
 
-#include <qdeclarativejsparser_p.h>
+#include <private/qdeclarativejsparser_p.h>
 
 static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
 {
     if (node->kind == QDeclarativeJS::AST::Node::Kind_IdentifierExpression) {
         QString name =
-            static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name->asString();
+            static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name.toString();
         return QStringList() << name;
     } else if (node->kind == QDeclarativeJS::AST::Node::Kind_FieldMemberExpression) {
         QDeclarativeJS::AST::FieldMemberExpression *expr = static_cast<QDeclarativeJS::AST::FieldMemberExpression *>(node);
@@ -2700,26 +3212,27 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
         QStringList rv = astNodeToStringList(expr->base);
         if (rv.isEmpty())
             return rv;
-        rv.append(expr->name->asString());
+        rv.append(expr->name.toString());
         return rv;
     }
     return QStringList();
 }
 
-bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
+bool QDeclarativeCompiler::compileAlias(QFastMetaBuilder &builder,
                                         QByteArray &data,
-                                        QDeclarativeParser::Object *obj,
-                                        const Object::DynamicProperty &prop)
+                                        QDeclarativeScript::Object *obj,
+                                        int propIndex, int aliasIndex,
+                                        Object::DynamicProperty &prop)
 {
     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?
 
@@ -2728,18 +3241,19 @@ 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)))
+    QDeclarativeScript::Object *idObject = compileState->ids.value(alias.at(0));
+    if (!idObject)
         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)];
-
     QByteArray typeName;
 
     int propIdx = -1;
     int flags = 0;
+    int type = 0;
     bool writable = false;
+    bool resettable = false;
     if (alias.count() == 2 || alias.count() == 3) {
-        propIdx = indexOfProperty(idObject, alias.at(1).toUtf8());
+        propIdx = indexOfProperty(idObject, alias.at(1));
 
         if (-1 == propIdx) {
             COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
@@ -2751,7 +3265,12 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
         if (!aliasProperty.isScriptable())
             COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
 
-        writable = aliasProperty.isWritable();
+        writable = aliasProperty.isWritable() && !prop.isReadOnly;
+        resettable = aliasProperty.isResettable() && !prop.isReadOnly;
+
+        if (aliasProperty.type() < QVariant::UserType
+            || uint(aliasProperty.type()) == QMetaType::QVariant)
+            type = aliasProperty.type();
 
         if (alias.count() == 3) {
             QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
@@ -2767,6 +3286,11 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
             
             aliasProperty = valueType->metaObject()->property(valueTypeIndex);
             propIdx |= (valueTypeIndex << 16);
+
+            // update the property type
+            type = aliasProperty.type();
+            if (type >= (int)QVariant::UserType)
+                type = 0;
         }
 
         if (aliasProperty.isEnumType()) 
@@ -2774,21 +3298,13 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
         else
             typeName = aliasProperty.typeName();
     } else {
-        typeName = idObject->metaObject()->className();
+        Q_ASSERT(idObject->type != -1); // How else did it get an id?
 
-        //use the base type since it has been registered with metatype system
-        int index = typeName.indexOf("_QML_");
-        if (index != -1) {
-            typeName = typeName.left(index);
-        } else {
-            index = typeName.indexOf("_QMLTYPE_");
-            const QMetaObject *mo = idObject->metaObject();
-            while (index != -1 && mo) {
-                typeName = mo->superClass()->className();
-                index = typeName.indexOf("_QMLTYPE_");
-                mo = mo->superClass();
-            }
-        }
+        const QDeclarativeCompiledData::TypeReference &ref = output->types.at(idObject->type);
+        if (ref.type)
+            typeName = ref.type->typeName();
+        else
+            typeName = ref.component->root->className();
 
         typeName += '*';
     }
@@ -2796,159 +3312,270 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
     if (typeName.endsWith('*'))
         flags |= QML_ALIAS_FLAG_PTR;
 
-    data.append((const char *)&idObject->idIndex, sizeof(idObject->idIndex));
-    data.append((const char *)&propIdx, sizeof(propIdx));
-    data.append((const char *)&flags, sizeof(flags));
+    QDeclarativeVMEMetaData::AliasData aliasData = { idObject->idIndex, propIdx, flags };
+
+    typedef QDeclarativeVMEMetaData VMD;
+    VMD *vmd = (QDeclarativeVMEMetaData *)data.data();
+    *(vmd->aliasData() + aliasIndex) = aliasData;
+
+    prop.nameRef = builder.newString(prop.name.utf8length());
+    prop.resolvedCustomTypeName = pool->NewByteArray(typeName);
+    prop.typeRef = builder.newString(typeName.length());
+
+    int propertyFlags = 0;
+    if (writable)
+        propertyFlags |= QFastMetaBuilder::Writable;
+    if (resettable)
+        propertyFlags |= QFastMetaBuilder::Resettable;
+
+    builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type, 
+                        (QFastMetaBuilder::PropertyFlag)propertyFlags,
+                        propIndex);
 
-    builder.addSignal(prop.name + "Changed()");
-    QMetaPropertyBuilder propBuilder = 
-        builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
-    propBuilder.setWritable(writable);
     return true;
 }
 
-bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
-                               QDeclarativeParser::Property *prop,
-                               const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildBinding(QDeclarativeScript::Value *value,
+                                        QDeclarativeScript::Property *prop,
+                                        const BindingContext &ctxt)
 {
     Q_ASSERT(prop->index != -1);
     Q_ASSERT(prop->parent);
     Q_ASSERT(prop->parent->metaObject());
 
-    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(QString::fromUtf8(prop->name)));
+    if (!prop->core.isWritable() && !prop->core.isQList() && !prop->isReadOnlyDeclaration)
+        COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
 
-    BindingReference reference;
-    reference.expression = value->value;
-    reference.property = prop;
-    reference.value = value;
-    reference.bindingContext = ctxt;
+    JSBindingReference *reference = pool->New<JSBindingReference>();
+    reference->expression = value->value;
+    reference->property = prop;
+    reference->value = value;
+    reference->bindingContext = ctxt;
     addBindingReference(reference);
 
     return true;
 }
 
-void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *binding,
-                                                QDeclarativeParser::Property *prop,
-                                                QDeclarativeParser::Object *obj,
-                                                QDeclarativeParser::Property *valueTypeProperty)
+bool QDeclarativeCompiler::buildLiteralBinding(QDeclarativeScript::Value *v,
+                                               QDeclarativeScript::Property *prop,
+                                               const QDeclarativeCompilerTypes::BindingContext &)
+{
+    Q_ASSERT(v->value.isScript());
+
+    if (!prop->core.isWritable())
+        return false;
+
+    AST::Node *binding = v->value.asAST();
+
+    if (prop->type == QVariant::String) {
+        if (AST::CallExpression *e = AST::cast<AST::CallExpression *>(binding)) {
+            if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(e->base)) {
+                if (i->name == qsTrId_string) {
+                    AST::ArgumentList *arg1 = e->arguments?e->arguments:0;
+                    AST::ArgumentList *arg2 = arg1?arg1->next:0;
+
+                    if (arg1 && arg1->expression->kind == AST::Node::Kind_StringLiteral &&
+                        (!arg2 || arg2->expression->kind == AST::Node::Kind_NumericLiteral) &&
+                        (!arg2 || !arg2->next)) {
+
+                        QStringRef text;
+                        int n = -1;
+
+                        text = AST::cast<AST::StringLiteral *>(arg1->expression)->value;
+                        if (arg2) n = (int)AST::cast<AST::NumericLiteral *>(arg2->expression)->value;
+
+                        TrBindingReference *reference = pool->New<TrBindingReference>();
+                        reference->dataType = BindingReference::TrId;
+                        reference->text = text;
+                        reference->n = n;
+                        v->bindingReference = reference;
+                        return true;
+                    }
+
+                } else if (i->name == qsTr_string) {
+
+                    AST::ArgumentList *arg1 = e->arguments?e->arguments:0;
+                    AST::ArgumentList *arg2 = arg1?arg1->next:0;
+                    AST::ArgumentList *arg3 = arg2?arg2->next:0;
+
+                    if (arg1 && arg1->expression->kind == AST::Node::Kind_StringLiteral &&
+                        (!arg2 || arg2->expression->kind == AST::Node::Kind_StringLiteral) &&
+                        (!arg3 || arg3->expression->kind == AST::Node::Kind_NumericLiteral) &&
+                        (!arg3 || !arg3->next)) {
+
+                        QStringRef text;
+                        QStringRef comment;
+                        int n = -1;
+
+                        text = AST::cast<AST::StringLiteral *>(arg1->expression)->value;
+                        if (arg2) comment = AST::cast<AST::StringLiteral *>(arg2->expression)->value;
+                        if (arg3) n = (int)AST::cast<AST::NumericLiteral *>(arg3->expression)->value;
+
+                        TrBindingReference *reference = pool->New<TrBindingReference>();
+                        reference->dataType = BindingReference::Tr;
+                        reference->text = text;
+                        reference->comment = comment;
+                        reference->n = n;
+                        v->bindingReference = reference;
+                        return true;
+                    }
+
+                }
+            }
+        }
+
+    }
+
+    return false;
+}
+
+void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *binding,
+                                                QDeclarativeScript::Property *prop,
+                                                QDeclarativeScript::Object *obj,
+                                                QDeclarativeScript::Property *valueTypeProperty)
 {
     Q_UNUSED(obj);
-    Q_ASSERT(compileState.bindings.contains(binding));
+    Q_ASSERT(binding->bindingReference);
 
-    const BindingReference &ref = compileState.bindings.value(binding);
-    if (ref.dataType == BindingReference::V4) {
-        QDeclarativeInstruction store;
-        store.setType(QDeclarativeInstruction::StoreV4Binding);
-        store.assignBinding.value = ref.compiledIndex;
-        store.assignBinding.context = ref.bindingContext.stack;
-        store.assignBinding.owner = ref.bindingContext.owner;
-        if (valueTypeProperty) 
-            store.assignBinding.property = (valueTypeProperty->index & 0xFFFF) |
-                                           ((valueTypeProperty->type & 0xFF)) << 16 |
-                                           ((prop->index & 0xFF) << 24);
-        else 
-            store.assignBinding.property = prop->index;
-        store.assignBinding.line = binding->location.start.line;
+    const BindingReference &ref = *binding->bindingReference;
+    if (ref.dataType == BindingReference::TrId) {
+        const TrBindingReference &tr = static_cast<const TrBindingReference &>(ref);
+
+        Instruction::StoreTrIdString store;
+        store.propertyIndex = prop->core.coreIndex;
+        store.text = output->indexForByteArray(tr.text.toUtf8());
+        store.n = tr.n;
+        output->addInstruction(store);
+    } else if (ref.dataType == BindingReference::Tr) {
+        const TrBindingReference &tr = static_cast<const TrBindingReference &>(ref);
+
+        Instruction::StoreTrString store;
+        store.propertyIndex = prop->core.coreIndex;
+        store.context = translationContextIndex();
+        store.text = output->indexForByteArray(tr.text.toUtf8());
+        store.comment = output->indexForByteArray(tr.comment.toUtf8());
+        store.n = tr.n;
+        output->addInstruction(store);
+    } else if (ref.dataType == BindingReference::V4) {
+        const JSBindingReference &js = static_cast<const JSBindingReference &>(ref);
+
+        Instruction::StoreV4Binding store;
+        store.value = js.compiledIndex;
+        store.context = js.bindingContext.stack;
+        store.owner = js.bindingContext.owner;
+        if (valueTypeProperty) {
+            store.property = (valueTypeProperty->index & 0xFFFF) |
+                             ((valueTypeProperty->type & 0xFF)) << 16 |
+                             ((prop->index & 0xFF) << 24);
+            store.isRoot = (compileState->root == valueTypeProperty->parent);
+        } else {
+            store.property = prop->index;
+            store.isRoot = (compileState->root == obj);
+        }
+        store.line = binding->location.start.line;
+        store.column = binding->location.start.column;
         output->addInstruction(store);
     } else if (ref.dataType == BindingReference::V8) {
-        QDeclarativeInstruction store;
-        store.setType(QDeclarativeInstruction::StoreV8Binding);
-        store.assignBinding.value = ref.compiledIndex;
-        store.assignBinding.context = ref.bindingContext.stack;
-        store.assignBinding.owner = ref.bindingContext.owner;
-        store.assignBinding.line = binding->location.start.line;
+        const JSBindingReference &js = static_cast<const JSBindingReference &>(ref);
+
+        Instruction::StoreV8Binding store;
+        store.value = js.compiledIndex;
+        store.context = js.bindingContext.stack;
+        store.owner = js.bindingContext.owner;
+        if (valueTypeProperty) {
+            store.isRoot = (compileState->root == valueTypeProperty->parent);
+        } else {
+            store.isRoot = (compileState->root == obj);
+        }
+        store.line = binding->location.start.line;
+        store.column = binding->location.start.column;
 
-        Q_ASSERT(ref.bindingContext.owner == 0 ||
-                 (ref.bindingContext.owner != 0 && valueTypeProperty));
-        if (ref.bindingContext.owner) {
-            store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
+        Q_ASSERT(js.bindingContext.owner == 0 ||
+                 (js.bindingContext.owner != 0 && valueTypeProperty));
+        if (js.bindingContext.owner) {
+            store.property = genValueTypeData(prop, valueTypeProperty);
         } else {
-            store.assignBinding.property = genPropertyData(prop);
+            store.property = prop->core;
         }
 
         output->addInstruction(store);
-    } else {
+    } else if (ref.dataType == BindingReference::QtScript) {
+        const JSBindingReference &js = static_cast<const JSBindingReference &>(ref);
+
         QDeclarativeInstruction store;
-        if (!prop->isAlias)
-            store.setType(QDeclarativeInstruction::StoreBinding);
-        else
-            store.setType(QDeclarativeInstruction::StoreBindingOnAlias);
-        store.assignBinding.value = output->indexForString(ref.rewrittenExpression);
-        store.assignBinding.context = ref.bindingContext.stack;
-        store.assignBinding.owner = ref.bindingContext.owner;
+        store.assignBinding.value = output->indexForString(js.rewrittenExpression);
+        store.assignBinding.context = js.bindingContext.stack;
+        store.assignBinding.owner = js.bindingContext.owner;
         store.assignBinding.line = binding->location.start.line;
+        store.assignBinding.column = binding->location.start.column;
 
-        Q_ASSERT(ref.bindingContext.owner == 0 ||
-                 (ref.bindingContext.owner != 0 && valueTypeProperty));
-        if (ref.bindingContext.owner) {
+        if (valueTypeProperty) {
+            store.assignBinding.isRoot = (compileState->root == valueTypeProperty->parent);
+        } else {
+            store.assignBinding.isRoot = (compileState->root == obj);
+        }
+
+        Q_ASSERT(js.bindingContext.owner == 0 ||
+                 (js.bindingContext.owner != 0 && valueTypeProperty));
+        if (js.bindingContext.owner) {
             store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
         } else {
-            store.assignBinding.property = genPropertyData(prop);
+            store.assignBinding.property = prop->core;
         }
-        output->addInstruction(store);
+        output->addInstructionHelper(
+            !prop->isAlias ? QDeclarativeInstruction::StoreBinding
+                           : QDeclarativeInstruction::StoreBindingOnAlias
+            , store);
+    } else {
+        Q_ASSERT(!"Unhandled BindingReference::DataType type");
     }
 }
 
 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();
-         ++iter) 
-        cache->add(iter.key(), (*iter)->idIndex);
+    cache->reserve(compileState->ids.count());
+    for (Object *o = compileState->ids.first(); o; o = compileState->ids.next(o)) 
+        cache->add(o->id, o->idIndex);
 
     output->contextCaches.append(cache);
     return output->contextCaches.count() - 1;
 }
 
-int QDeclarativeCompiler::genValueTypeData(QDeclarativeParser::Property *valueTypeProp, 
-                                  QDeclarativeParser::Property *prop)
+QDeclarativePropertyData
+QDeclarativeCompiler::genValueTypeData(QDeclarativeScript::Property *valueTypeProp, 
+                                       QDeclarativeScript::Property *prop)
 {
     typedef QDeclarativePropertyPrivate QDPP;
-    QByteArray data = QDPP::saveValueType(prop->parent->metaObject(), prop->index, 
-                                          enginePrivate->valueTypes[prop->type]->metaObject(), 
-                                          valueTypeProp->index, engine);
-
-    return output->indexForByteArray(data);
-}
-
-int QDeclarativeCompiler::genPropertyData(QDeclarativeParser::Property *prop)
-{
-    typedef QDeclarativePropertyPrivate QDPP;
-    QByteArray data = QDPP::saveProperty(prop->parent->metaObject(), prop->index, engine);
-
-    return output->indexForByteArray(data);
+    return QDPP::saveValueType(prop->parent->metaObject(), prop->index, 
+                               enginePrivate->valueTypes[prop->type]->metaObject(), 
+                               valueTypeProp->index, engine);
 }
 
 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 (Object *aliasObject = compileState->aliasingObjects.first(); aliasObject; 
+         aliasObject = compileState->aliasingObjects.next(aliasObject)) 
         COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
-    }
 
-    QDeclarativeV4Compiler::Expression expr;
-    expr.component = compileState.root;
-    expr.ids = compileState.ids;
+    QV4Compiler::Expression expr(unit->imports());
+    expr.component = compileState->root;
+    expr.ids = &compileState->ids;
     expr.importCache = output->importCache;
-    expr.imports = unit->imports();
 
-    QDeclarativeV4Compiler bindingCompiler;
+    QV4Compiler bindingCompiler;
 
-    QList<BindingReference*> sharedBindings;
+    QList<JSBindingReference*> sharedBindings;
 
-    for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); 
-         iter != compileState.bindings.end(); ++iter) {
+    for (JSBindingReference *b = compileState->bindings.first(); b; b = b->nextReference) {
 
-        BindingReference &binding = *iter;
+        JSBindingReference &binding = *b;
 
         // ### We don't currently optimize for bindings on alias's - because 
         // of the solution to QTBUG-13719
@@ -2961,7 +3588,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;
             } 
         }
@@ -2970,24 +3598,25 @@ bool QDeclarativeCompiler::completeComponentBuild()
         QString expression = binding.expression.asScript();
 
         QDeclarativeRewrite::RewriteBinding rewriteBinding;
-        rewriteBinding.setName('$'+binding.property->name);
+        rewriteBinding.setName(QLatin1Char('$')+binding.property->name().toString());
         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()) {
         struct Sort {
-            static bool lt(const BindingReference *lhs, const BindingReference *rhs)
+            static bool lt(const JSBindingReference *lhs, const JSBindingReference *rhs)
             {
                 return lhs->value->location.start.line < rhs->value->location.start.line;
             }
@@ -3000,8 +3629,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
 
         QString functionArray(QLatin1String("["));
         for (int ii = 0; ii < sharedBindings.count(); ++ii) {
-            BindingReference *reference = sharedBindings.at(ii);
-            QDeclarativeParser::Value *value = reference->value;
+            JSBindingReference *reference = sharedBindings.at(ii);
+            QDeclarativeScript::Value *value = reference->value;
             const QString &expression = reference->rewrittenExpression;
 
             if (ii != 0) functionArray += QLatin1String(",");
@@ -3012,18 +3641,23 @@ bool QDeclarativeCompiler::completeComponentBuild()
             }
 
             functionArray += expression;
+            lineNumber += expression.count(QLatin1Char('\n'));
             reference->compiledIndex = ii;
         }
         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();
+
+    // Check pop()'s matched push()'s
+    Q_ASSERT(compileState->objectDepth.depth() == 0);
+    Q_ASSERT(compileState->listDepth.depth() == 0);
 
     saveComponentState();
 
@@ -3032,9 +3666,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;
@@ -3083,10 +3718,9 @@ void QDeclarativeCompiler::dumpStats()
     Returns true if from can be assigned to a (QObject) property of type
     to.
 */
-bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from)
+bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeScript::Object *from)
 {
-    const QMetaObject *toMo = 
-        enginePrivate->rawMetaObjectForType(to);
+    const QMetaObject *toMo = enginePrivate->rawMetaObjectForType(to);
     const QMetaObject *fromMo = from->metaObject();
 
     while (fromMo) {
@@ -3097,7 +3731,20 @@ bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from)
     return false;
 }
 
-QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeParser::Object *from)
+/*!
+    Returns the element name, as written in the QML file, for o.
+*/
+QString QDeclarativeCompiler::elementName(QDeclarativeScript::Object *o)
+{
+    Q_ASSERT(o);
+    if (o->type != -1) {
+        return output->types.at(o->type).className;
+    } else {
+        return QString();
+    }
+}
+
+QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeScript::Object *from)
 {
     // ### Optimize
     const QMetaObject *mo = from->metatype;
@@ -3109,7 +3756,7 @@ QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeParser::Object *fr
    return type;
 }
 
-QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object *obj)
+QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeScript::Object *obj)
 {
     const QMetaObject *mo = obj->metatype;
 
@@ -3122,74 +3769,108 @@ QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object
     return rv;
 }
 
-// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
-int QDeclarativeCompiler::indexOfSignal(QDeclarativeParser::Object *object, const QByteArray &name, 
-                                        bool *notInRevision)
+QDeclarativePropertyData *
+QDeclarativeCompiler::property(QDeclarativeScript::Object *object, int index)
 {
-    if (notInRevision) *notInRevision = false;
+    QDeclarativePropertyCache *cache = 0;
 
-    if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
-        // XXX fromUtf8
-        QString strName(QString::fromUtf8(name));
-        QDeclarativePropertyCache *cache = 
-            object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
+    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());
 
-        QDeclarativePropertyCache::Data *d = cache->property(strName);
-        if (notInRevision) *notInRevision = false;
+    return cache->property(index);
+}
 
-        while (d && !(d->isFunction()))
-            d = cache->overrideData(d);
+QDeclarativePropertyData *
+QDeclarativeCompiler::property(QDeclarativeScript::Object *object, const QHashedStringRef &name, bool *notInRevision)
+{
+    if (notInRevision) *notInRevision = false;
 
-        if (d && !cache->isAllowedInRevision(d)) {
-            if (notInRevision) *notInRevision = true;
-            return -1;
-        } else if (d) {
-            return d->coreIndex;
-        }
+    QDeclarativePropertyCache *cache = 0;
 
-        if (name.endsWith("Changed")) {
-            QByteArray propName = name.mid(0, name.length() - 7);
+    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());
 
-            int propIndex = indexOfProperty(object, propName, notInRevision);
-            if (propIndex != -1) {
-                d = cache->property(propIndex);
-                return d->notifyIndex;
-            }
-        }
+    QDeclarativePropertyData *d = cache->property(name);
 
-        return -1;
+    // Find the first property
+    while (d && d->isFunction())
+        d = cache->overrideData(d);
+
+    if (d && !cache->isAllowedInRevision(d)) {
+        if (notInRevision) *notInRevision = true;
+        return 0;
     } else {
-        return QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), name).methodIndex();
+        return d;
     }
-
 }
 
-int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QByteArray &name, 
-                                          bool *notInRevision)
+// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
+QDeclarativePropertyData *
+QDeclarativeCompiler::signal(QDeclarativeScript::Object *object, const QHashedStringRef &name, bool *notInRevision)
 {
     if (notInRevision) *notInRevision = false;
 
-    if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
-        // XXX fromUtf8
-        QString strName(QString::fromUtf8(name));
-        QDeclarativePropertyCache *cache = 
-            object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
+    QDeclarativePropertyCache *cache = 0;
 
-        QDeclarativePropertyCache::Data *d = cache->property(strName);
-        // 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;
-        }
-    } else {
-        const QMetaObject *mo = object->metaObject();
-        return mo->indexOfProperty(name.constData());
+
+    QDeclarativePropertyData *d = cache->property(name);
+    if (notInRevision) *notInRevision = false;
+
+    while (d && !(d->isFunction()))
+        d = cache->overrideData(d);
+
+    if (d && !cache->isAllowedInRevision(d)) {
+        if (notInRevision) *notInRevision = true;
+        return 0;
+    } else if (d) {
+        return d;
+    }
+
+    if (name.endsWith(Changed_string)) {
+        QHashedStringRef propName = name.mid(0, name.length() - Changed_string.length());
+
+        d = property(object, propName, notInRevision);
+        if (d) 
+            return cache->method(d->notifyIndex);
     }
+
+    return 0;
+}
+
+// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
+int QDeclarativeCompiler::indexOfSignal(QDeclarativeScript::Object *object, const QString &name, 
+                                        bool *notInRevision)
+{
+    QDeclarativePropertyData *d = signal(object, QStringRef(&name), notInRevision);
+    return d?d->coreIndex:-1;
+}
+
+int QDeclarativeCompiler::indexOfProperty(QDeclarativeScript::Object *object, const QString &name, 
+                                          bool *notInRevision)
+{
+    return indexOfProperty(object, QStringRef(&name), notInRevision);
+}
+
+int QDeclarativeCompiler::indexOfProperty(QDeclarativeScript::Object *object, const QHashedStringRef &name, 
+                                          bool *notInRevision)
+{
+    QDeclarativePropertyData *d = property(object, name, notInRevision);
+    return d?d->coreIndex:-1;
 }
 
 QT_END_NAMESPACE