aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/libshiboken
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/libshiboken')
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp5
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.cpp73
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.h6
3 files changed, 62 insertions, 22 deletions
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp
index f34e053ca..15c79479e 100644
--- a/sources/shiboken6/libshiboken/basewrapper.cpp
+++ b/sources/shiboken6/libshiboken/basewrapper.cpp
@@ -1007,11 +1007,6 @@ introduceWrapperType(PyObject *enclosingObject,
auto *type = SbkType_FromSpecBasesMeta(typeSpec, bases, SbkObjectType_TypeF());
- for (Py_ssize_t i = 0; i < basesSize; ++i) {
- auto *st = reinterpret_cast<PyTypeObject *>(PySequence_Fast_GET_ITEM(bases, i));
- BindingManager::instance().addClassInheritance(st, type);
- }
-
auto sotp = PepType_SOTP(type);
if (wrapperFlags & DeleteInMainThread)
sotp->delete_in_main_thread = 1;
diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp
index 60460c6ab..83c927ae5 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken6/libshiboken/bindingmanager.cpp
@@ -7,6 +7,7 @@
#include "bindingmanager.h"
#include "gilstate.h"
#include "helper.h"
+#include "sbkmodule.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkfeature_base.h"
@@ -21,6 +22,29 @@
#include <unordered_map>
#include <unordered_set>
+// GraphNode for the dependency graph. It keeps a pointer to
+// the TypeInitStruct to be able to lazily create the type and hashes
+// by the full type name.
+struct GraphNode
+{
+ explicit GraphNode(Shiboken::Module::TypeInitStruct *i) : name(i->fullName), initStruct(i) {}
+ explicit GraphNode(const char *n) : name(n), initStruct(nullptr) {} // Only for searching
+
+ std::string_view name;
+ Shiboken::Module::TypeInitStruct *initStruct;
+
+ friend bool operator==(const GraphNode &n1, const GraphNode &n2) { return n1.name == n2.name; }
+ friend bool operator!=(const GraphNode &n1, const GraphNode &n2) { return n1.name != n2.name; }
+};
+
+template <>
+struct std::hash<GraphNode> {
+ size_t operator()(const GraphNode &n) const noexcept
+ {
+ return std::hash<std::string_view>{}(n.name);
+ }
+};
+
namespace Shiboken
{
@@ -56,28 +80,45 @@ public:
}
};
-class Graph : public BaseGraph<PyTypeObject *>
+class Graph : public BaseGraph<GraphNode>
{
public:
- Graph() = default;
+ using TypeCptrPair = BindingManager::TypeCptrPair;
- BindingManager::TypeCptrPair identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const;
+ TypeCptrPair identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const
+ {
+ return identifyType(cptr, GraphNode(type->tp_name), type, baseType);
+ }
bool dumpTypeGraph(const char *fileName) const;
+
+private:
+ TypeCptrPair identifyType(void *cptr, const GraphNode &typeNode, PyTypeObject *type,
+ PyTypeObject *baseType) const;
};
-BindingManager::TypeCptrPair Graph::identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const
+Graph::TypeCptrPair Graph::identifyType(void *cptr,
+ const GraphNode &typeNode, PyTypeObject *type,
+ PyTypeObject *baseType) const
{
- auto edgesIt = m_edges.find(type);
+ assert(typeNode.initStruct != nullptr || type != nullptr);
+ auto edgesIt = m_edges.find(typeNode);
if (edgesIt != m_edges.end()) {
const NodeList &adjNodes = edgesIt->second;
- for (PyTypeObject *node : adjNodes) {
- auto newType = identifyType(cptr, node, baseType);
+ for (const auto &node : adjNodes) {
+ auto newType = identifyType(cptr, node, nullptr, baseType);
if (newType.first != nullptr)
return newType;
}
}
+ if (type == nullptr) {
+ if (typeNode.initStruct->type == nullptr) // Layzily create type
+ type = Shiboken::Module::get(*typeNode.initStruct);
+ else
+ type = typeNode.initStruct->type;
+ }
+
auto *sotp = PepType_SOTP(type);
if (sotp->type_discovery != nullptr) {
if (void *derivedCPtr = sotp->type_discovery(cptr, baseType))
@@ -86,9 +127,8 @@ BindingManager::TypeCptrPair Graph::identifyType(void *cptr, PyTypeObject *type,
return {nullptr, nullptr};
}
-static void formatDotNode(const char *nameC, std::ostream &file)
+static void formatDotNode(std::string_view name, std::ostream &file)
{
- std::string_view name(nameC);
auto lastDot = name.rfind('.');
file << " \"" << name << "\" [ label=";
if (lastDot != std::string::npos) {
@@ -109,15 +149,15 @@ bool Graph::dumpTypeGraph(const char *fileName) const
file << "digraph D {\n";
// Define nodes with short names
- for (const auto *node : nodeSet())
- formatDotNode(node->tp_name, file);
+ for (const auto &node : nodeSet())
+ formatDotNode(node.name, file);
// Write edges
for (const auto &p : m_edges) {
- auto *node1 = p.first;
+ const auto &node1 = p.first;
const NodeList &nodeList = p.second;
- for (const PyTypeObject *node2 : nodeList)
- file << " \"" << node2->tp_name << "\" -> \"" << node1->tp_name << "\"\n";
+ for (const auto &node2 : nodeList)
+ file << " \"" << node2.name << "\" -> \"" << node1.name << "\"\n";
}
file << "}\n";
return true;
@@ -380,9 +420,10 @@ PyObject *BindingManager::getOverride(const void *cptr,
return nullptr;
}
-void BindingManager::addClassInheritance(PyTypeObject *parent, PyTypeObject *child)
+void BindingManager::addClassInheritance(Module::TypeInitStruct *parent,
+ Module::TypeInitStruct *child)
{
- m_d->classHierarchy.addEdge(parent, child);
+ m_d->classHierarchy.addEdge(GraphNode(parent), GraphNode(child));
}
BindingManager::TypeCptrPair BindingManager::findDerivedType(void *cptr, PyTypeObject *type) const
diff --git a/sources/shiboken6/libshiboken/bindingmanager.h b/sources/shiboken6/libshiboken/bindingmanager.h
index 281de2c73..54c4e486a 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.h
+++ b/sources/shiboken6/libshiboken/bindingmanager.h
@@ -15,6 +15,10 @@ struct SbkObject;
namespace Shiboken
{
+namespace Module {
+struct TypeInitStruct;
+}
+
struct DestructorEntry;
using ObjectVisitor = void (*)(SbkObject *, void *);
@@ -40,7 +44,7 @@ public:
SbkObject *retrieveWrapper(const void *cptr);
PyObject *getOverride(const void *cptr, PyObject *nameCache[], const char *methodName);
- void addClassInheritance(PyTypeObject *parent, PyTypeObject *child);
+ void addClassInheritance(Module::TypeInitStruct *parent, Module::TypeInitStruct *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.