From bbd32e9e52bda460dd1cb75d128dd1165d1fd152 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Oct 2018 13:30:08 +0200 Subject: libpyside: Introduce helper functions for accessing TypeUserData and meta objects Add helpers with overloads to reduce reinterpret_cast<> and increase type safety. Task-number: PYSIDE-784 Change-Id: I334fd7d149a6730094b062dd0371b9a29379d725 Reviewed-by: Qt CI Bot Reviewed-by: Alexandru Croitor --- .../PySide2/QtQml/pysideqmlregistertype.cpp | 4 +- sources/pyside2/libpyside/pyside.cpp | 50 ++++++++++++++++------ sources/pyside2/libpyside/pyside_p.h | 11 +++++ sources/pyside2/libpyside/pysideclassinfo.cpp | 11 +++-- sources/pyside2/libpyside/signalmanager.cpp | 4 +- 5 files changed, 56 insertions(+), 24 deletions(-) (limited to 'sources/pyside2') diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp index 0b427c251..4e45cfdcc 100644 --- a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp +++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp @@ -44,6 +44,7 @@ // pyside #include +#include #include // auto generated headers @@ -126,8 +127,7 @@ int PySide::qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, return -1; } - QMetaObject *metaObject = reinterpret_cast( - ObjectType::getTypeUserData(reinterpret_cast(pyObj))); + const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); Q_ASSERT(metaObject); QQmlPrivate::RegisterType type; diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp index 18bec1001..856e5b92c 100644 --- a/sources/pyside2/libpyside/pyside.cpp +++ b/sources/pyside2/libpyside/pyside.cpp @@ -192,9 +192,7 @@ void destroyQCoreApplication() std::size_t getSizeOfQObject(SbkObjectType* type) { - using namespace Shiboken::ObjectType; - TypeUserData* userData = reinterpret_cast(getTypeUserData(reinterpret_cast(type))); - return userData->cppObjSize; + return retrieveTypeUserData(type)->cppObjSize; } void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, std::size_t cppObjSize) @@ -214,6 +212,36 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, std::si PyObject_SetAttrString(reinterpret_cast(type), "staticMetaObject", pyMetaObject); } +TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj) +{ + return reinterpret_cast(Shiboken::ObjectType::getTypeUserData(sbkTypeObj)); +} + +TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj) +{ + return retrieveTypeUserData(reinterpret_cast(pyTypeObj)); +} + +TypeUserData *retrieveTypeUserData(PyObject *pyObj) +{ + auto pyTypeObj = PyType_Check(pyObj) + ? reinterpret_cast(pyObj) : Py_TYPE(pyObj); + return retrieveTypeUserData(pyTypeObj); +} + +DynamicQMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj) +{ + TypeUserData *userData = retrieveTypeUserData(pyTypeObj); + return userData ? &(userData->mo) : nullptr; +} + +DynamicQMetaObject *retrieveMetaObject(PyObject *pyObj) +{ + auto pyTypeObj = PyType_Check(pyObj) + ? reinterpret_cast(pyObj) : Py_TYPE(pyObj); + return retrieveMetaObject(pyTypeObj); +} + void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base) { initDynamicMetaObject(type, base, 0); @@ -226,26 +254,22 @@ void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds PyObject* bases = PyTuple_GET_ITEM(args, 1); int numBases = PyTuple_GET_SIZE(bases); - DynamicQMetaObject *baseMo = nullptr; - SbkObjectType* qobjBase = 0; + + TypeUserData *userData = nullptr; for (int i = 0; i < numBases; ++i) { PyTypeObject* base = reinterpret_cast(PyTuple_GET_ITEM(bases, i)); if (PyType_IsSubtype(base, qObjType)) { - void *typeUserData = Shiboken::ObjectType::getTypeUserData(reinterpret_cast(base)); - baseMo = &(reinterpret_cast(typeUserData)->mo); - qobjBase = reinterpret_cast(base); - baseMo->update(); + userData = retrieveTypeUserData(base); break; } } - if (!baseMo) { + if (!userData) { qWarning("Sub class of QObject not inheriting QObject!? Crash will happen when using %s.", className.constData()); return; } - - TypeUserData* userData = reinterpret_cast(Shiboken::ObjectType::getTypeUserData(qobjBase)); - initDynamicMetaObject(type, baseMo, userData->cppObjSize); + userData->mo.update(); + initDynamicMetaObject(type, &userData->mo, userData->cppObjSize); } PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* name) diff --git a/sources/pyside2/libpyside/pyside_p.h b/sources/pyside2/libpyside/pyside_p.h index e3039ed0b..66a37fc7a 100644 --- a/sources/pyside2/libpyside/pyside_p.h +++ b/sources/pyside2/libpyside/pyside_p.h @@ -40,8 +40,12 @@ #ifndef PYSIDE_P_H #define PYSIDE_P_H +#include + #include +struct SbkObjectType; + namespace PySide { @@ -55,6 +59,13 @@ struct TypeUserData std::size_t cppObjSize; }; +TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj); +TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj); +TypeUserData *retrieveTypeUserData(PyObject *pyObj); +// For QML +PYSIDE_API DynamicQMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj); +PYSIDE_API DynamicQMetaObject *retrieveMetaObject(PyObject *pyObj); + } //namespace PySide #endif // PYSIDE_P_H diff --git a/sources/pyside2/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp index e3a437438..88b2b89f5 100644 --- a/sources/pyside2/libpyside/pysideclassinfo.cpp +++ b/sources/pyside2/libpyside/pysideclassinfo.cpp @@ -97,8 +97,7 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */) return 0; } - PyObject* klass; - klass = PyTuple_GetItem(args, 0); + PyObject *klass = PyTuple_GetItem(args, 0); bool validClass = false; // This will sometimes segfault if you mistakenly use it on a function declaration @@ -107,10 +106,10 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */) return 0; } - if (Shiboken::ObjectType::checkType(reinterpret_cast(klass))) { - if (void *userData = Shiboken::ObjectType::getTypeUserData(reinterpret_cast(klass))) { - PySide::DynamicQMetaObject &mo = reinterpret_cast(userData)->mo; - mo.addInfo(PySide::ClassInfo::getMap(data)); + PyTypeObject *klassType = reinterpret_cast(klass); + if (Shiboken::ObjectType::checkType(klassType)) { + if (PySide::DynamicQMetaObject *mo = PySide::retrieveMetaObject(klassType)) { + mo->addInfo(PySide::ClassInfo::getMap(data)); pData->m_alreadyWrapped = true; validClass = true; } diff --git a/sources/pyside2/libpyside/signalmanager.cpp b/sources/pyside2/libpyside/signalmanager.cpp index 07160d989..f505fde5a 100644 --- a/sources/pyside2/libpyside/signalmanager.cpp +++ b/sources/pyside2/libpyside/signalmanager.cpp @@ -609,9 +609,7 @@ const QMetaObject* SignalManager::retrieveMetaObject(PyObject *self) mo = reinterpret_cast(PyCObject_AsVoidPtr(pyMo)); #endif } else { - void *userData = Shiboken::Object::getTypeUserData(reinterpret_cast(self)); - Q_ASSERT(userData); - mo = &(reinterpret_cast(userData)->mo); + mo = PySide::retrieveMetaObject(self); } mo->update(); -- cgit v1.2.3