diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-07-14 03:54:55 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-07-15 07:30:16 (GMT) |
commit | 4f7e21dc04ce93531ef68f7694a5e8969448de8b (patch) | |
tree | ce7e8170b5be6c974420d012a03f620f86cd6d8d /src/corelib | |
parent | 9eca9e028884fb82d97e284826faa7965af356bd (diff) | |
download | Qt-4f7e21dc04ce93531ef68f7694a5e8969448de8b.zip Qt-4f7e21dc04ce93531ef68f7694a5e8969448de8b.tar.gz Qt-4f7e21dc04ce93531ef68f7694a5e8969448de8b.tar.bz2 |
Rework compiler to a two phase analyse/generate approach
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 81 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder_p.h | 2 |
2 files changed, 76 insertions, 7 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 8775c5c..e6817fe 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1167,8 +1167,10 @@ static QByteArray buildParameterNames // Build a QMetaObject in "buf" based on the information in "d". // If "buf" is null, then return the number of bytes needed to -// build the QMetaObject. -static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf) +// build the QMetaObject. Returns -1 if the metaobject if +// relocatable is set, but the metaobject contains extradata. +static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, + bool relocatable) { int size = 0; int dataIndex; @@ -1176,18 +1178,23 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf) int index; bool hasNotifySignals = false; + if (relocatable && + (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction)) + return -1; + // Create the main QMetaObject structure at the start of the buffer. QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf); size += sizeof(QMetaObject); ALIGN(size, int); if (buf) { - meta->d.superdata = d->superClass; + if (!relocatable) meta->d.superdata = d->superClass; meta->d.extradata = 0; } // Populate the QMetaObjectPrivate structure. QMetaObjectPrivate *pmeta = reinterpret_cast<QMetaObjectPrivate *>(buf + size); + int pmetaSize = size; dataIndex = 13; // Number of fields in the QMetaObjectPrivate. for (index = 0; index < d->properties.size(); ++index) { if (d->properties[index].notifySignal != -1) { @@ -1246,8 +1253,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf) size += dataIndex * sizeof(int); char *str = reinterpret_cast<char *>(buf + size); if (buf) { - meta->d.stringdata = str; - meta->d.data = reinterpret_cast<uint *>(data); + if (relocatable) { + meta->d.stringdata = reinterpret_cast<const char *>((intptr_t)size); + meta->d.data = reinterpret_cast<uint *>((intptr_t)pmetaSize); + } else { + meta->d.stringdata = str; + meta->d.data = reinterpret_cast<uint *>(data); + } } // Reset the current data position to just past the QMetaObjectPrivate. @@ -1422,12 +1434,67 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf) */ QMetaObject *QMetaObjectBuilder::toMetaObject() const { - int size = buildMetaObject(d, 0); + int size = buildMetaObject(d, 0, false); char *buf = reinterpret_cast<char *>(qMalloc(size)); - buildMetaObject(d, buf); + buildMetaObject(d, buf, false); return reinterpret_cast<QMetaObject *>(buf); } +/* + \internal + + Converts this meta object builder into relocatable data. This data can + be stored, copied and later passed to fromRelocatableData() to create a + concrete QMetaObject. + + The data is specific to the architecture on which it was created, but is not + specific to the process that created it. Not all meta object builder's can + be converted to data in this way. If \a ok is provided, it will be set to + true if the conversion succeeds, and false otherwise. If a + staticMetacallFunction() or any relatedMetaObject()'s are specified the + conversion to relocatable data will fail. +*/ +QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const +{ + int size = buildMetaObject(d, 0, true); + if (size == -1) { + if (ok) *ok = false; + return QByteArray(); + } + + QByteArray data; + data.resize(size); + char *buf = data.data(); + buildMetaObject(d, buf, true); + if (ok) *ok = true; + return data; +} + +/* + \internal + + Sets the \a data returned from toRelocatableData() onto a concrete + QMetaObject instance, \a output. As the meta object's super class is not + saved in the relocatable data, it must be passed as \a superClass. +*/ +void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output, + const QMetaObject *superclass, + const QByteArray &data) +{ + if (!output) + return; + + const char *buf = data.constData(); + const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf); + + intptr_t stringdataOffset = (intptr_t)dataMo->d.stringdata; + intptr_t dataOffset = (intptr_t)dataMo->d.data; + + output->d.superdata = superclass; + output->d.stringdata = buf + stringdataOffset; + output->d.data = reinterpret_cast<const uint *>(buf + dataOffset); +} + /*! \typedef QMetaObjectBuilder::StaticMetacallFunction diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index 952364a..d503163 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -169,6 +169,8 @@ public: void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value); QMetaObject *toMetaObject() const; + QByteArray toRelocatableData(bool * = 0) const; + static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &); #ifndef QT_NO_DATASTREAM void serialize(QDataStream& stream) const; |