diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-04-24 12:47:13 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-04-25 11:32:21 +0200 |
commit | ce2959ec5135965ef67476274a8b4a57c897f4cf (patch) | |
tree | d7dc74f089f85265b07053e287175e1791d11d26 | |
parent | cbdc4518cc089971677676449a9478d70d4a2441 (diff) |
libshiboken: Refactor type discovery graph handling
Replace BindingManager::.resolveType() by
a new function BindingManager::findDerivedType()
which does exactly that and returns a pair of type/cptr
instead of modifying the in-parameter.
As a drive-by, remove a unused variable in BindingManagerPrivate.
Task-number: PYSIDE-2404
Task-number: PYSIDE-2675
Pick-to: 6.7
Change-Id: I5b39ea8370b0fc1a196feb6934306f1f1dfeb8b3
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
-rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.cpp | 11 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/bindingmanager.cpp | 60 | ||||
-rw-r--r-- | sources/shiboken6/libshiboken/bindingmanager.h | 14 |
3 files changed, 51 insertions, 34 deletions
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp index 3cd8a5c2b..f34e053ca 100644 --- a/sources/shiboken6/libshiboken/basewrapper.cpp +++ b/sources/shiboken6/libshiboken/basewrapper.cpp @@ -1460,10 +1460,15 @@ PyObject *newObject(PyTypeObject *instanceType, { // Try to find the exact type of cptr. if (!isExactType) { - if (PyTypeObject *exactType = ObjectType::typeForTypeName(typeName)) + if (PyTypeObject *exactType = ObjectType::typeForTypeName(typeName)) { instanceType = exactType; - else - instanceType = BindingManager::instance().resolveType(&cptr, instanceType); + } else { + auto resolved = BindingManager::instance().findDerivedType(cptr, instanceType); + if (resolved.first != nullptr) { + instanceType = resolved.first; + cptr = resolved.second; + } + } } bool shouldCreate = true; diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp index 7542e60b8..84424a78a 100644 --- a/sources/shiboken6/libshiboken/bindingmanager.cpp +++ b/sources/shiboken6/libshiboken/bindingmanager.cpp @@ -43,35 +43,32 @@ public: m_edges[from].push_back(to); } + BindingManager::TypeCptrPair identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const; + bool dumpTypeGraph(const char *fileName) const; NodeSet nodeSet() const; - PyTypeObject *identifyType(void **cptr, PyTypeObject *type, PyTypeObject *baseType) const - { - auto edgesIt = m_edges.find(type); - if (edgesIt != m_edges.end()) { - const NodeList &adjNodes = m_edges.find(type)->second; - for (PyTypeObject *node : adjNodes) { - PyTypeObject *newType = identifyType(cptr, node, baseType); - if (newType) - return newType; - } - } - void *typeFound = nullptr; - auto *sotp = PepType_SOTP(type); - if (sotp->type_discovery) - typeFound = sotp->type_discovery(*cptr, baseType); - if (typeFound) { - // This "typeFound != type" is needed for backwards compatibility with old modules using a newer version of - // libshiboken because old versions of type_discovery function used to return a PyTypeObject *instead of - // a possible variation of the C++ instance pointer (*cptr). - if (typeFound != type) - *cptr = typeFound; - return type; +}; + +BindingManager::TypeCptrPair Graph::identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const +{ + auto edgesIt = m_edges.find(type); + if (edgesIt != m_edges.end()) { + const NodeList &adjNodes = edgesIt->second; + for (PyTypeObject *node : adjNodes) { + auto newType = identifyType(cptr, node, baseType); + if (newType.first != nullptr) + return newType; } - return nullptr; } -}; + + auto *sotp = PepType_SOTP(type); + if (sotp->type_discovery != nullptr) { + if (void *derivedCPtr = sotp->type_discovery(cptr, baseType)) + return {type, derivedCPtr}; + } + return {nullptr, nullptr}; +} static void formatDotNode(const char *nameC, std::ostream &file) { @@ -132,9 +129,6 @@ struct BindingManager::BindingManagerPrivate { std::recursive_mutex wrapperMapLock; Graph classHierarchy; DestructorEntries deleteInMainThread; - bool destroying; - - BindingManagerPrivate() : destroying(false) {} bool releaseWrapper(void *cptr, SbkObject *wrapper, const int *bases = nullptr); bool releaseWrapperHelper(void *cptr, SbkObject *wrapper); @@ -386,10 +380,18 @@ void BindingManager::addClassInheritance(PyTypeObject *parent, PyTypeObject *chi m_d->classHierarchy.addEdge(parent, child); } +BindingManager::TypeCptrPair BindingManager::findDerivedType(void *cptr, PyTypeObject *type) const +{ + return m_d->classHierarchy.identifyType(cptr, type, type); +} + +// FIXME PYSIDE7: remove, just for compatibility PyTypeObject *BindingManager::resolveType(void **cptr, PyTypeObject *type) { - PyTypeObject *identifiedType = m_d->classHierarchy.identifyType(cptr, type, type); - return identifiedType ? identifiedType : type; + auto result = findDerivedType(*cptr, type); + if (result.second != nullptr) + *cptr = result.second; + return result.first != nullptr ? result.first : type; } std::set<PyObject *> BindingManager::getAllPyObjects() diff --git a/sources/shiboken6/libshiboken/bindingmanager.h b/sources/shiboken6/libshiboken/bindingmanager.h index 47db14975..281de2c73 100644 --- a/sources/shiboken6/libshiboken/bindingmanager.h +++ b/sources/shiboken6/libshiboken/bindingmanager.h @@ -5,9 +5,11 @@ #define BINDINGMANAGER_H #include "sbkpython.h" -#include <set> #include "shibokenmacros.h" +#include <set> +#include <utility> + struct SbkObject; namespace Shiboken @@ -39,6 +41,14 @@ public: PyObject *getOverride(const void *cptr, PyObject *nameCache[], const char *methodName); void addClassInheritance(PyTypeObject *parent, PyTypeObject *child); + /// Try to find the correct type of cptr via type discovery knowing that it's at least + /// of type \p type. If a derived class is found, it returns a cptr cast to the type + /// (which may be different in case of multiple inheritance. + /// \param cptr a pointer to the instance of type \p type + /// \param type type of cptr + using TypeCptrPair = std::pair<PyTypeObject *, void *>; + TypeCptrPair findDerivedType(void *cptr, PyTypeObject *type) const; + /** * Try to find the correct type of *cptr knowing that it's at least of type \p type. * In case of multiple inheritance this function may change the contents of cptr. @@ -46,7 +56,7 @@ public: * \param type type of *cptr * \warning This function is slow, use it only as last resort. */ - PyTypeObject *resolveType(void **cptr, PyTypeObject *type); + [[deprecated]] PyTypeObject *resolveType(void **cptr, PyTypeObject *type); std::set<PyObject *> getAllPyObjects(); |