diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-12-16 16:59:33 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-12-16 16:59:33 +0100 |
commit | 3f3be55835427ea9f1bbcc046e05ee538ca214d7 (patch) | |
tree | 09d1f54d114855c2b06cc505dfbf74c5890c8419 /src/corelib/kernel | |
parent | ae293c1cb220847194fba6dcebdbb9194837bb56 (diff) | |
parent | 9764f8602719676d1fa15e6fd1e7980af16bfc63 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/gui/kernel/qplatformtheme.h
tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
Change-Id: Iecd3343d6a050b8764f78d809c4a1532aeba69e5
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qjni.cpp | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 52 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder_p.h | 5 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 44 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 19 |
5 files changed, 91 insertions, 32 deletions
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 4e06d12aee..aaa75c0fb8 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -74,7 +74,8 @@ static jclass getCachedClass(JNIEnv *env, const char *className) if (!classLoader.isValid()) return 0; - QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(QLatin1String(className)); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(QString::fromLatin1(className).replace(QLatin1Char('/'), + QLatin1Char('.'))); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", stringName.object()); diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 2a02df1186..09d8271413 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1075,8 +1075,14 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name) \brief The QMetaStringTable class can generate a meta-object string table at runtime. */ -QMetaStringTable::QMetaStringTable() - : m_index(0) {} +QMetaStringTable::QMetaStringTable(const QByteArray &className) + : m_index(0) + , m_className(className) +{ + const int index = enter(m_className); + Q_ASSERT(index == 0); + Q_UNUSED(index); +} // Enters the given value into the string table (if it hasn't already been // entered). Returns the index of the string. @@ -1106,30 +1112,45 @@ int QMetaStringTable::blobSize() const return size; } +static void writeString(char *out, int i, const QByteArray &str, + const int offsetOfStringdataMember, int &stringdataOffset) +{ + int size = str.size(); + qptrdiff offset = offsetOfStringdataMember + stringdataOffset + - i * sizeof(QByteArrayData); + const QByteArrayData data = + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset); + + memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData)); + + memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size); + out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; + + stringdataOffset += size + 1; +} + // Writes strings to string data struct. // The struct consists of an array of QByteArrayData, followed by a char array // containing the actual strings. This format must match the one produced by // moc (see generator.cpp). -void QMetaStringTable::writeBlob(char *out) +void QMetaStringTable::writeBlob(char *out) const { Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1))); int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData); int stringdataOffset = 0; - for (int i = 0; i < m_entries.size(); ++i) { - const QByteArray &str = m_entries.key(i); - int size = str.size(); - qptrdiff offset = offsetOfStringdataMember + stringdataOffset - - i * sizeof(QByteArrayData); - const QByteArrayData data = - Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset); - memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData)); + // qt_metacast expects the first string in the string table to be the class name. + writeString(out, /*index*/0, m_className, offsetOfStringdataMember, stringdataOffset); - memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size); - out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; + for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd(); + it != end; ++it) { + const int i = it.value(); + if (i == 0) + continue; + const QByteArray &str = it.key(); - stringdataOffset += size + 1; + writeString(out, i, str, offsetOfStringdataMember, stringdataOffset); } } @@ -1270,8 +1291,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Reset the current data position to just past the QMetaObjectPrivate. dataIndex = MetaObjectPrivateFieldCount; - QMetaStringTable strings; - strings.enter(d->className); + QMetaStringTable strings(d->className); // Output the class infos, Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index f79ce2f2f1..3a1b43c3ed 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -323,18 +323,19 @@ private: class Q_CORE_EXPORT QMetaStringTable { public: - QMetaStringTable(); + explicit QMetaStringTable(const QByteArray &className); int enter(const QByteArray &value); static int preferredAlignment(); int blobSize() const; - void writeBlob(char *out); + void writeBlob(char *out) const; private: typedef QHash<QByteArray, int> Entries; // string --> index mapping Entries m_entries; int m_index; + QByteArray m_className; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 4ccfc7b7f0..745487627e 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -783,6 +783,10 @@ struct IteratorOwner { *ptr = new const_iterator(iterator); } + static void assign(void **ptr, void * const * src) + { + *ptr = new const_iterator(*static_cast<const_iterator*>(*src)); + } static void advance(void **iterator, int step) { @@ -804,18 +808,27 @@ struct IteratorOwner { return &*it; } + + static bool equal(void * const *it, void * const *other) + { + return *static_cast<const_iterator*>(*it) == *static_cast<const_iterator*>(*other); + } }; -template<typename const_iterator> -struct IteratorOwner<const const_iterator*> +template<typename value_type> +struct IteratorOwner<const value_type*> { - static void assign(void **ptr, const const_iterator *iterator ) + static void assign(void **ptr, const value_type *iterator ) { - *ptr = const_cast<const_iterator*>(iterator); + *ptr = const_cast<value_type*>(iterator); + } + static void assign(void **ptr, void * const * src) + { + *ptr = static_cast<value_type*>(*src); } static void advance(void **iterator, int step) { - const_iterator *it = static_cast<const_iterator*>(*iterator); + value_type *it = static_cast<value_type*>(*iterator); std::advance(it, step); *iterator = it; } @@ -829,10 +842,15 @@ struct IteratorOwner<const const_iterator*> return *iterator; } - static const void *getData(const const_iterator *it) + static const void *getData(const value_type *it) { return it; } + + static bool equal(void * const *it, void * const *other) + { + return static_cast<value_type*>(*it) == static_cast<value_type*>(*other); + } }; enum IteratorCapability @@ -934,7 +952,7 @@ public: template<class T> static bool equalIterImpl(void * const *iterator, void * const *other) - { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); } + { return IteratorOwner<typename T::const_iterator>::equal(iterator, other); } template<class T> static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags) @@ -942,7 +960,7 @@ public: template<class T> static void copyIterImpl(void **dest, void * const * src) - { IteratorOwner<typename T::const_iterator>::assign(dest, *static_cast<typename T::const_iterator*>(*src)); } + { IteratorOwner<typename T::const_iterator>::assign(dest, src); } public: template<class T> QSequentialIterableImpl(const T*p) @@ -1118,11 +1136,11 @@ public: template<class T> static bool equalIterImpl(void * const *iterator, void * const *other) - { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); } + { return IteratorOwner<typename T::const_iterator>::equal(iterator, other); } template<class T> static void copyIterImpl(void **dest, void * const * src) - { IteratorOwner<typename T::const_iterator>::assign(dest, *static_cast<typename T::const_iterator*>(*src)); } + { IteratorOwner<typename T::const_iterator>::assign(dest, src); } public: template<class T> QAssociativeIterableImpl(const T*p) @@ -1741,7 +1759,7 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \ return id; \ const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \ Q_ASSERT(tName); \ - const int tNameLen = qstrlen(tName); \ + const int tNameLen = int(qstrlen(tName)); \ QByteArray typeName; \ typeName.reserve(int(sizeof(#SINGLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + 1); \ typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \ @@ -1782,8 +1800,8 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \ const char *uName = QMetaType::typeName(qMetaTypeId<U>()); \ Q_ASSERT(tName); \ Q_ASSERT(uName); \ - const int tNameLen = qstrlen(tName); \ - const int uNameLen = qstrlen(uName); \ + const int tNameLen = int(qstrlen(tName)); \ + const int uNameLen = int(qstrlen(uName)); \ QByteArray typeName; \ typeName.reserve(int(sizeof(#DOUBLE_ARG_TEMPLATE)) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \ typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \ diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5880b96f32..8e0dc4dede 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -194,9 +194,15 @@ QMetaObject *QObjectData::dynamicMetaObject() const QObjectPrivate::QObjectPrivate(int version) : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0) { +#ifdef QT_BUILD_INTERNAL + // Don't check the version parameter in internal builds. + // This allows incompatible versions to be loaded, possibly for testing. + Q_UNUSED(version); +#else if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)", version, QObjectPrivateVersion); +#endif // QObjectData initialization q_ptr = 0; @@ -3090,6 +3096,10 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal, expensive initialization only if something is connected to a signal. + \warning This function is called from the thread which performs the + connection, which may be a different thread from the thread in + which this object lives. + \sa connect(), disconnectNotify() */ @@ -3116,6 +3126,15 @@ void QObject::connectNotify(const QMetaMethod &signal) modularity. However, it might be useful for optimizing access to expensive resources. + \warning This function is called from the thread which performs the + disconnection, which may be a different thread from the thread in + which this object lives. This function may also be called with a QObject + internal mutex locked. It is therefore not allowed to re-enter any + of any QObject functions from your reimplementation and if you lock + a mutex in your reimplementation, make sure that you don't call QObject + functions with that mutex held in other places or it will result in + a deadlock. + \sa disconnect(), connectNotify() */ |