aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-07-20 17:47:57 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-30 13:18:28 +0200
commit28fcf9485b496c986b0b8c88a194d76bec132b4c (patch)
treec543df77e1d827b953ea616487c40f20a9c5e52d /src/declarative
parentff18fc0cee6ec7e9f39bb4cfb381e32f495d028f (diff)
Add QFastMetaBuilder
This is a faster, but less convenient, version of QMetaObjectBuilder. The aim is to reduce allocations made during building the meta object by doing it in two passes - first you reserve all the strings needed and then you provide their data. Change-Id: Id9caf9c9c6c2ab6a5219e5cea9363463a4ebf822 Reviewed-on: http://codereview.qt.nokia.com/3763 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/ftw/ftw.pri5
-rw-r--r--src/declarative/qml/ftw/qfastmetabuilder.cpp371
-rw-r--r--src/declarative/qml/ftw/qfastmetabuilder_p.h194
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp444
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h5
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp24
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h20
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp5
8 files changed, 914 insertions, 154 deletions
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
index 190296a93e..7e88598728 100644
--- a/src/declarative/qml/ftw/ftw.pri
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -9,7 +9,8 @@ HEADERS += \
$$PWD/qdeclarativerefcount_p.h \
$$PWD/qdeclarativepool_p.h \
$$PWD/qfieldlist_p.h \
- $$PWD/qdeclarativeutils_p.h
+ $$PWD/qdeclarativeutils_p.h \
+ $$PWD/qfastmetabuilder_p.h \
SOURCES += \
$$PWD/qintrusivelist.cpp \
@@ -17,3 +18,5 @@ SOURCES += \
$$PWD/qhashedstring.cpp \
$$PWD/qdeclarativerefcount.cpp \
$$PWD/qdeclarativepool.cpp \
+ $$PWD/qfastmetabuilder.cpp \
+
diff --git a/src/declarative/qml/ftw/qfastmetabuilder.cpp b/src/declarative/qml/ftw/qfastmetabuilder.cpp
new file mode 100644
index 0000000000..20c5e08499
--- /dev/null
+++ b/src/declarative/qml/ftw/qfastmetabuilder.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfastmetabuilder_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct QFastMetaBuilderHeader
+{
+ int fieldCount;
+};
+
+struct QMetaObjectPrivate
+{
+ int revision;
+ int className;
+ int classInfoCount, classInfoData;
+ int methodCount, methodData;
+ int propertyCount, propertyData;
+ int enumeratorCount, enumeratorData;
+ int constructorCount, constructorData; //since revision 2
+ int flags; //since revision 3
+ int signalCount; //since revision 4
+};
+
+enum MetaObjectFlag {
+ DynamicMetaObject = 0x01
+};
+
+enum PropertyFlags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ EnumOrFlag = 0x00000008,
+ StdCppSet = 0x00000100,
+// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
+ Designable = 0x00001000,
+ ResolveDesignable = 0x00002000,
+ Scriptable = 0x00004000,
+ ResolveScriptable = 0x00008000,
+ Stored = 0x00010000,
+ ResolveStored = 0x00020000,
+ Editable = 0x00040000,
+ ResolveEditable = 0x00080000,
+ User = 0x00100000,
+ ResolveUser = 0x00200000,
+ Notify = 0x00400000,
+ Revisioned = 0x00800000
+};
+
+enum MethodFlags {
+ AccessPrivate = 0x00,
+ AccessProtected = 0x01,
+ AccessPublic = 0x02,
+ AccessMask = 0x03, //mask
+
+ MethodMethod = 0x00,
+ MethodSignal = 0x04,
+ MethodSlot = 0x08,
+ MethodConstructor = 0x0c,
+ MethodTypeMask = 0x0c,
+
+ MethodCompatibility = 0x10,
+ MethodCloned = 0x20,
+ MethodScriptable = 0x40,
+ MethodRevisioned = 0x80
+};
+
+#define FMBHEADER_FIELD_COUNT 1
+
+#define HEADER_FIELD_COUNT 14
+#define CLASSINFO_FIELD_COUNT 2
+#define METHOD_FIELD_COUNT 5
+#define PROPERTY_FIELD_COUNT 3
+#define PROPERTY_NOTIFY_FIELD_COUNT 1
+
+static inline uint *fieldPointer(QByteArray &data)
+{ return reinterpret_cast<uint *>(data.data()) + FMBHEADER_FIELD_COUNT; }
+
+static inline const uint *fieldPointer(const QByteArray &data)
+{ return reinterpret_cast<const uint *>(data.constData()) + FMBHEADER_FIELD_COUNT; }
+
+static inline QMetaObjectPrivate *priv(QByteArray &data)
+{ return reinterpret_cast<QMetaObjectPrivate*>(fieldPointer(data)); }
+
+static inline const QMetaObjectPrivate *priv(const QByteArray &data)
+{ return reinterpret_cast<const QMetaObjectPrivate*>(fieldPointer(data)); }
+
+static inline QFastMetaBuilderHeader *header(QByteArray &data)
+{ return reinterpret_cast<QFastMetaBuilderHeader*>(data.data()); }
+
+static inline const QFastMetaBuilderHeader *header(const QByteArray &data)
+{ return reinterpret_cast<const QFastMetaBuilderHeader*>(data.constData()); }
+
+QFastMetaBuilder::QFastMetaBuilder()
+: m_zeroPtr(0), m_stringData(0), m_stringDataLength(0), m_stringDataAllocated(0)
+{
+}
+
+QFastMetaBuilder::~QFastMetaBuilder()
+{
+}
+
+QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
+ int propertyCount, int methodCount,
+ int signalCount, int classInfoCount)
+{
+ Q_ASSERT(m_data.isEmpty());
+ Q_ASSERT(classNameLength > 0);
+ Q_ASSERT(propertyCount >= 0);
+ Q_ASSERT(methodCount >= 0);
+ Q_ASSERT(signalCount >= 0);
+ Q_ASSERT(classInfoCount >= 0);
+
+ int fieldCount = FMBHEADER_FIELD_COUNT +
+ HEADER_FIELD_COUNT +
+ propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT) +
+ methodCount * (METHOD_FIELD_COUNT) +
+ signalCount * (METHOD_FIELD_COUNT) +
+ classInfoCount * CLASSINFO_FIELD_COUNT;
+
+ m_data.resize(fieldCount * sizeof(uint) + classNameLength + 1);
+ m_stringData = m_data.data() + m_data.size() - classNameLength - 1;
+ m_stringDataLength = classNameLength + 1;
+ m_stringDataAllocated = classNameLength + 1;
+ m_stringData[classNameLength] = 0;
+ m_zeroPtr = classNameLength;
+
+ header(m_data)->fieldCount = fieldCount;
+
+ QMetaObjectPrivate *p = priv(m_data);
+
+ int dataIndex = HEADER_FIELD_COUNT;
+
+ p->revision = 4;
+ p->className = 0;
+
+ // Class infos
+ p->classInfoCount = classInfoCount;
+ if (p->classInfoCount) {
+ p->classInfoData = dataIndex;
+ dataIndex += p->classInfoCount * CLASSINFO_FIELD_COUNT;
+ } else {
+ p->classInfoData = 0;
+ }
+
+ // Methods
+ p->methodCount = methodCount + signalCount;
+ if (p->methodCount) {
+ p->methodData = dataIndex;
+ dataIndex += p->methodCount * METHOD_FIELD_COUNT;
+ } else {
+ p->methodData = 0;
+ }
+ p->signalCount = signalCount;
+
+ // Properties
+ p->propertyCount = propertyCount;
+ if (p->propertyCount) {
+ p->propertyData = dataIndex;
+ dataIndex += p->propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT);
+ } else {
+ p->propertyData = 0;
+ }
+
+ // Flags
+ p->flags = DynamicMetaObject; // Always dynamic
+
+ // Enums and constructors not supported
+ p->enumeratorCount = 0;
+ p->enumeratorData = 0;
+ p->constructorCount = 0;
+ p->constructorData = 0;
+
+ StringRef className;
+ className._b = this;
+ className._o = 0;
+ className._l = classNameLength;
+ return className;
+}
+
+// Allocate a string of \a length. \a length should *not* include the null terminator.
+QFastMetaBuilder::StringRef QFastMetaBuilder::newString(int length)
+{
+ Q_ASSERT(length > 0);
+
+ StringRef sr;
+ sr._b = this;
+ sr._o = m_stringDataLength;
+ sr._l = length;
+
+ m_stringDataLength += length + 1 /* for null terminator */;
+
+ return sr;
+}
+
+void QFastMetaBuilder::setClassInfo(int index, const StringRef &key, const StringRef &value)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!key.isEmpty() && !value.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->classInfoCount);
+
+ uint *ptr = fieldPointer(m_data) + p->classInfoData + index * CLASSINFO_FIELD_COUNT;
+ // classinfo: key, value
+ ptr[0] = key.offset(); ptr[1] = value.offset();
+}
+
+void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
+ QMetaType::Type mtype, PropertyFlag flags, int notifySignal)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!name.isEmpty() && !type.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->propertyCount);
+
+ uint qtType = mtype;
+ if ((int)qtType == qMetaTypeId<QVariant>())
+ qtType = 0xFF; // Special handling for QVariant
+
+ uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
+ // properties: name, type, flags
+ ptr[0] = name.offset();
+ ptr[1] = type.offset();
+ if (notifySignal == -1) {
+ ptr[2] = qtType << 24;
+ ptr[2] |= flags | Scriptable | Readable;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
+ } else {
+ ptr[2] = qtType << 24;
+ ptr[2] |= flags | Scriptable | Readable | Notify;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal;
+ }
+}
+
+void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
+ QFastMetaBuilder::PropertyFlag flags, int notifySignal)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!name.isEmpty() && !type.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->propertyCount);
+
+ uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
+ // properties: name, type, flags
+ ptr[0] = name.offset();
+ ptr[1] = type.offset();
+ if (notifySignal == -1) {
+ ptr[2] = flags | Scriptable | Readable;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
+ } else {
+ ptr[2] = flags | Scriptable | Readable | Notify;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal;
+ }
+}
+
+void QFastMetaBuilder::setSignal(int index, const StringRef &signature,
+ const StringRef &parameterNames,
+ const StringRef &type)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!signature.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ int mindex = metaObjectIndexForSignal(index);
+
+ uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
+ // methods: signature, parameters, type, tag, flags
+ ptr[0] = signature.offset();
+ ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
+ ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
+ ptr[3] = m_zeroPtr;
+ ptr[4] = AccessProtected | MethodSignal;
+}
+
+void QFastMetaBuilder::setMethod(int index, const StringRef &signature,
+ const StringRef &parameterNames,
+ const StringRef &type)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!signature.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ int mindex = metaObjectIndexForMethod(index);
+
+ uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
+ // methods: signature, parameters, type, tag, flags
+ ptr[0] = signature.offset();
+ ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
+ ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
+ ptr[3] = m_zeroPtr;
+ ptr[4] = AccessProtected | MethodSlot;
+}
+
+int QFastMetaBuilder::metaObjectIndexForSignal(int index) const
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(index < priv(m_data)->signalCount);
+ return index;
+}
+
+int QFastMetaBuilder::metaObjectIndexForMethod(int index) const
+{
+ Q_ASSERT(!m_data.isEmpty());
+
+ const QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < (p->methodCount - p->signalCount));
+ return index + p->signalCount;
+}
+
+void QFastMetaBuilder::allocateStringData()
+{
+ if (m_stringDataAllocated < m_stringDataLength) {
+ m_data.resize(m_data.size() + m_stringDataLength - m_stringDataAllocated);
+ m_stringDataAllocated = m_stringDataLength;
+ m_stringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint);
+ }
+}
+
+void QFastMetaBuilder::fromData(QMetaObject *output, const QMetaObject *parent, const QByteArray &data)
+{
+ output->d.superdata = parent;
+ output->d.stringdata = data.constData() + header(data)->fieldCount * sizeof(uint);
+ output->d.data = fieldPointer(data);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qfastmetabuilder_p.h b/src/declarative/qml/ftw/qfastmetabuilder_p.h
new file mode 100644
index 0000000000..c0cb0fc2fb
--- /dev/null
+++ b/src/declarative/qml/ftw/qfastmetabuilder_p.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFASTMETABUILDER_P_H
+#define QFASTMETABUILDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of moc. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFastMetaBuilder
+{
+public:
+ QFastMetaBuilder();
+ ~QFastMetaBuilder();
+
+ struct StringRef {
+ public:
+ inline StringRef();
+ inline StringRef(const StringRef &);
+ inline StringRef &operator=(const StringRef &);
+
+ inline void load(const QByteArray &);
+ inline void load(const char *);
+
+ inline bool isEmpty() const;
+ inline QFastMetaBuilder *builder() const;
+ inline int offset() const;
+ inline char *data();
+ inline int length() const;
+ private:
+ friend class QFastMetaBuilder;
+
+ QFastMetaBuilder *_b;
+ int _o;
+ int _l;
+ };
+ StringRef newString(int length);
+
+ // Returns class name
+ StringRef init(int classNameLength,
+ int propertyCount, int methodCount,
+ int signalCount, int classInfoCount);
+
+ void setClassInfo(int index, const StringRef &key, const StringRef &value);
+
+ enum PropertyFlag {
+ None = 0x00000000,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ Constant = 0x00000400,
+ Final = 0x00000800
+ };
+ // void setProperty(int index, const StringRef &name, QMetaType::Type type, int notifySignal = -1);
+ void setProperty(int index, const StringRef &name, const StringRef &type,
+ QMetaType::Type mtype, PropertyFlag flags, int notifySignal = -1);
+ void setProperty(int index, const StringRef &name, const StringRef &type,
+ PropertyFlag flags, int notifySignal = -1);
+ void setMethod(int index, const StringRef &signature,
+ const StringRef &parameterNames = StringRef(),
+ const StringRef &type = StringRef());
+ void setSignal(int index, const StringRef &signature,
+ const StringRef &parameterNames = StringRef(),
+ const StringRef &type = StringRef());
+
+ int metaObjectIndexForSignal(int) const;
+ int metaObjectIndexForMethod(int) const;
+
+ QByteArray toData() const { return m_data; }
+ static void fromData(QMetaObject *, const QMetaObject *parent, const QByteArray &);
+private:
+ friend class StringRef;
+
+ QByteArray m_data;
+ int m_zeroPtr;
+
+ void allocateStringData();
+ char *m_stringData;
+ int m_stringDataLength;
+ int m_stringDataAllocated;
+};
+
+QFastMetaBuilder::StringRef::StringRef()
+: _b(0), _o(0), _l(0)
+{
+}
+
+QFastMetaBuilder::StringRef::StringRef(const StringRef &o)
+: _b(o._b), _o(o._o), _l(o._l)
+{
+}
+
+QFastMetaBuilder::StringRef &QFastMetaBuilder::StringRef::operator=(const StringRef &o)
+{
+ _b = o._b;
+ _o = o._o;
+ _l = o._l;
+ return *this;
+}
+
+bool QFastMetaBuilder::StringRef::isEmpty() const
+{
+ return _l == 0;
+}
+
+QFastMetaBuilder *QFastMetaBuilder::StringRef::builder() const
+{
+ return _b;
+}
+
+int QFastMetaBuilder::StringRef::offset() const
+{
+ return _o;
+}
+
+char *QFastMetaBuilder::StringRef::data()
+{
+ Q_ASSERT(_b);
+ if (_b->m_stringDataLength != _b->m_stringDataAllocated)
+ _b->allocateStringData();
+ return _b->m_stringData + _o;
+}
+
+int QFastMetaBuilder::StringRef::length() const
+{
+ return _l;
+}
+
+void QFastMetaBuilder::StringRef::load(const QByteArray &str)
+{
+ Q_ASSERT(str.length() == _l);
+ strcpy(data(), str.constData());
+}
+
+void QFastMetaBuilder::StringRef::load(const char *str)
+{
+ Q_ASSERT(strlen(str) == _l);
+ strcpy(data(), str);
+}
+
+QT_END_NAMESPACE
+
+#endif // QFASTMETABUILDER_P_H
+
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 984e2c8b51..95d1ffbbb4 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -46,6 +46,7 @@
#include "qdeclarativepropertyvaluesource.h"
#include "qdeclarativecomponent.h"
#include "private/qmetaobjectbuilder_p.h"
+#include "private/qfastmetabuilder_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
@@ -2489,53 +2490,114 @@ 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;
+
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+
+ if (p.type == Object::DynamicProperty::Alias)
+ aliasCount++;
+
+ 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
+ QString name = QString::fromUtf8(p.name);
+ QDeclarativePropertyCache::Data *d = property(obj, QStringRef(&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));
+ 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() && QDeclarativeUtils::isUpper(nameBase.at(0)))
- newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(idx);
+ newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(uniqueClassId);
}
}
- 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);
+ 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::Variant, 0, "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 (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ Object::DynamicProperty &p = obj->dynamicProperties[ii];
+
+ // Reserve space for name
+ p.nameRef = builder.newString(p.name.length());
+
+ 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];
+ if (p.type == Object::DynamicProperty::Variant)
+ propertyType = qMetaTypeId<QVariant>();
- 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);
-
- 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;
QString url;
@@ -2556,144 +2618,216 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
}
if (p.type == Object::DynamicProperty::Custom) {
- type = customTypeName + '*';
+ 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 = customTypeName;
+ p.typeRef = builder.newString(customTypeName.length());
+ typeRef = p.typeRef;
}
- 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;
- }
- ((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++;
- QDeclarativeVMEMetaData::PropertyData propertyData = { propertyType };
- dynamicData.append((char *)&propertyData, sizeof(propertyData));
+ if (buildData) {
+ VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+ vmd->propertyCount++;
+ (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType;
+ }
- builder.addSignal(p.name + "Changed()");
- QMetaPropertyBuilder propBuilder =
- builder.addProperty(p.name, type, builder.methodCount() - 1);
- propBuilder.setWritable(!readonly);
- }
+ 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);
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ p.changedSignatureRef = builder.newString(p.name.length() + strlen("Changed()"));
+ builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
- 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()");
+ effectivePropertyIndex++;
+ }
+
+ if (aliasCount) {
+ int aliasIndex = 0;
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ Object::DynamicProperty &p = obj->dynamicProperties[ii];
+ 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.length() + strlen("Changed()"));
+ builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
+ effectivePropertyIndex++;
+ aliasIndex++;
+ }
}
}
}
+ // Reserve default property
+ QFastMetaBuilder::StringRef defPropRef;
+ if (defaultProperty) {
+ defPropRef = builder.newString(strlen("DefaultProperty"));
+ builder.setClassInfo(0, defPropRef, defaultProperty->nameRef);
+ }
+
+ // Reserve dynamic signals
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));
- }
- sig.append(')');
- QMetaMethodBuilder b = builder.addSignal(sig);
- b.setParameterNames(s.parameterNames);
- ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
+ Object::DynamicSignal &s = obj->dynamicSignals[ii];
+
+ int paramCount = s.parameterNames.count();
+
+ int signatureSize = s.name.length() + 2 /* paren */;
+ int namesSize = 0;
+ if (paramCount) signatureSize += s.parameterTypesLength() + (paramCount - 1) /* commas */;
+ if (paramCount) namesSize += s.parameterNamesLength() + (paramCount - 1) /* commas */;
+
+ s.signatureRef = builder.newString(signatureSize);
+ if (namesSize) s.parameterNamesRef = builder.newString(namesSize);
+
+ if (buildData)
+ ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
+
+ builder.setSignal(ii + obj->dynamicProperties.count(), s.signatureRef, s.parameterNamesRef);
}
- QStringList funcScripts;
+ // Reserve dynamic slots
+ if (obj->dynamicSlots.count()) {
- 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('('));
+ // Allocate QVariant string
+ if (typeRefs[0].isEmpty())
+ typeRefs[0] = builder.newString(strlen(builtinTypes[0].cppType));
- for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
- if (jj) {
- sig.append(',');
- funcScript.append(QLatin1Char(','));
+ typedef QDeclarativeVMEMetaData VMD;
+
+ for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
+ Object::DynamicSlot &s = obj->dynamicSlots[ii];
+ int paramCount = s.parameterNames.count();
+
+ int signatureSize = s.name.length() + 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(ii, 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 + 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() + ii);
+ md = methodData;
+ md.bodyOffset = dynamicData.size();
+
+ dynamicData.append((const char *)funcScript.constData(),
+ (funcScript.length() * sizeof(QChar)));
}
- funcScript.append(QLatin1String(s.parameterNames.at(jj)));
- sig.append("QVariant");
+
}
- sig.append(')');
- funcScript.append(QLatin1Char(')'));
- funcScript.append(s.body);
- funcScript.append(QLatin1Char(')'));
- funcScripts << funcScript;
+ }
- QMetaMethodBuilder b = builder.addSlot(sig);
- b.setReturnType("QVariant");
- b.setParameterNames(s.parameterNames);
+ // Now allocate used builtin types
+ for (int ii = 0; ii < builtinTypeCount; ++ii) {
+ if (!typeRefs[ii].isEmpty())
+ typeRefs[ii].load(builtinTypes[ii].cppType);
+ }
+
+ // Now allocate properties
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ Object::DynamicProperty &p = obj->dynamicProperties[ii];
+
+ char *d = p.changedSignatureRef.data();
+ strcpy(d, p.name.constData());
+ strcpy(d + p.name.length(), "Changed()");
+
+ 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)
+ 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 (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
+ Object::DynamicSignal &s = obj->dynamicSignals[ii];
- data->bodyOffset = dynamicData.size();
+ char *d = s.signatureRef.data();
+ char *d2 = s.parameterNamesRef.isEmpty()?0:s.parameterNamesRef.data();
+ strcpy(d, s.name.constData());
+ d += s.name.length();
+ *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();
+ strcpy(d2, s.parameterNames.at(jj).constData());
+ d2 += s.parameterNames.at(jj).length();
+ }
+ *d++ = ')';
+ *d = 0;
+ if (d2) *d2 = 0;
+ }
- dynamicData.append((const char *)funcScript.constData(),
- (funcScript.length() * sizeof(QChar)));
+ // Now allocate methods
+ for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
+ Object::DynamicSlot &s = obj->dynamicSlots[ii];
+ char *d = s.signatureRef.data();
+ char *d2 = s.parameterNamesRef.isEmpty()?0:s.parameterNamesRef.data();
+ strcpy(d, s.name.constData());
+ d += s.name.length();
+ *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);
- if (mode == IgnoreAliases && hasAlias)
+ obj->metadata = builder.toData();
+ builder.fromData(&obj->extObject, obj->metatype, obj->metadata);
+
+ if (mode == IgnoreAliases && aliasCount)
compileState->aliasingObjects.append(obj);
obj->synthdata = dynamicData;
@@ -2759,10 +2893,11 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
return QStringList();
}
-bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
+bool QDeclarativeCompiler::compileAlias(QFastMetaBuilder &builder,
QByteArray &data,
QDeclarativeParser::Object *obj,
- const Object::DynamicProperty &prop)
+ int propIndex, int aliasIndex,
+ Object::DynamicProperty &prop)
{
if (!prop.defaultValue)
COMPILE_EXCEPTION(obj, tr("No property alias location"));
@@ -2789,6 +2924,7 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
int propIdx = -1;
int flags = 0;
+ int type = 0;
bool writable = false;
bool resettable = false;
if (alias.count() == 2 || alias.count() == 3) {
@@ -2807,6 +2943,9 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
writable = aliasProperty.isWritable();
resettable = aliasProperty.isResettable();
+ if (aliasProperty.type() < QVariant::UserType)
+ type = aliasProperty.type();
+
if (alias.count() == 3) {
QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
if (!valueType)
@@ -2842,15 +2981,20 @@ 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.length());
+ prop.resolvedCustomTypeName = typeName;
+ prop.typeRef = builder.newString(typeName.length());
+
+ builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type,
+ (QFastMetaBuilder::PropertyFlag)(writable?int(QFastMetaBuilder::Writable):0),
+ propIndex);
- builder.addSignal(prop.name + "Changed()");
- QMetaPropertyBuilder propBuilder =
- builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
- propBuilder.setWritable(writable);
- propBuilder.setResettable(resettable);
return true;
}
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 66d094e886..e8f5c6ac52 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -301,10 +301,11 @@ private:
bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop,
const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
- bool compileAlias(QMetaObjectBuilder &,
+ bool compileAlias(QFastMetaBuilder &,
QByteArray &data,
QDeclarativeParser::Object *obj,
- const QDeclarativeParser::Object::DynamicProperty &);
+ int propIndex, int aliasIndex,
+ QDeclarativeParser::Object::DynamicProperty &);
bool completeComponentBuild();
bool checkValidId(QDeclarativeParser::Value *, const QString &);
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
index 9f08ae8dc0..a34eceb456 100644
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ b/src/declarative/qml/qdeclarativeparser.cpp
@@ -195,6 +195,22 @@ QDeclarativeParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
{
}
+int QDeclarativeParser::Object::DynamicSignal::parameterTypesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterTypes.count(); ++ii)
+ rv += parameterTypes.at(ii).length();
+ return rv;
+}
+
+int QDeclarativeParser::Object::DynamicSignal::parameterNamesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterNames.count(); ++ii)
+ rv += parameterNames.at(ii).length();
+ return rv;
+}
+
QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
{
}
@@ -204,6 +220,14 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
{
}
+int QDeclarativeParser::Object::DynamicSlot::parameterNamesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterNames.count(); ++ii)
+ rv += parameterNames.at(ii).length();
+ return rv;
+}
+
QDeclarativeParser::Property::Property()
: parent(0), type(0), index(-1), value(0), _name(0), isDefault(true), isDeferred(false),
isValueTypeSubProperty(false), isAlias(false), scriptStringScope(-1), nextProperty(0),
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 0d39c20979..023cb9cd07 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -67,6 +67,7 @@
#include <private/qdeclarativepool_p.h>
#include <private/qfieldlist_p.h>
#include <private/qdeclarativepropertycache_p.h>
+#include <private/qfastmetabuilder_p.h>
QT_BEGIN_HEADER
@@ -374,6 +375,12 @@ namespace QDeclarativeParser
QByteArray name;
QDeclarativeParser::Property *defaultValue;
LocationSpan location;
+
+ // Used by the compiler
+ QByteArray resolvedCustomTypeName;
+ QFastMetaBuilder::StringRef typeRef;
+ QFastMetaBuilder::StringRef nameRef;
+ QFastMetaBuilder::StringRef changedSignatureRef;
};
struct DynamicSignal {
DynamicSignal();
@@ -382,6 +389,13 @@ namespace QDeclarativeParser
QByteArray name;
QList<QByteArray> parameterTypes;
QList<QByteArray> parameterNames;
+
+ int parameterTypesLength() const;
+ int parameterNamesLength() const;
+
+ // Used by the compiler
+ QFastMetaBuilder::StringRef signatureRef;
+ QFastMetaBuilder::StringRef parameterNamesRef;
};
struct DynamicSlot {
DynamicSlot();
@@ -391,6 +405,12 @@ namespace QDeclarativeParser
QString body;
QList<QByteArray> parameterNames;
LocationSpan location;
+
+ int parameterNamesLength() const;
+
+ // Used by the compiler
+ QFastMetaBuilder::StringRef signatureRef;
+ QFastMetaBuilder::StringRef parameterNamesRef;
};
// The list of dynamic properties
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index dae1ba0030..e631dbbc08 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -45,6 +45,7 @@
#include "private/qdeclarativeboundsignal_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qmetaobjectbuilder_p.h"
+#include "private/qfastmetabuilder_p.h"
#include "private/qdeclarativedata_p.h"
#include "qdeclarative.h"
#include "private/qdeclarativecustomparser_p.h"
@@ -356,7 +357,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QMetaObject mo;
const QByteArray &metadata = datas.at(instr.data);
- QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
+ QFastMetaBuilder::fromData(&mo, 0, metadata);
+// QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
+
const QDeclarativeVMEMetaData *data =
(const QDeclarativeVMEMetaData *)datas.at(instr.aliasData).constData();