aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/shiboken/cppgenerator.cpp
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2024-02-12 16:24:37 +0100
committerChristian Tismer <tismer@stackless.com>2024-03-13 14:53:07 +0100
commit7accf7c3042e3f0680fa0615a0f13b54d28a0efd (patch)
treee9f0c87d5bcb67a74a5a60be8374277eb48f545c /sources/shiboken6/generator/shiboken/cppgenerator.cpp
parenta6ebf276fd654dd63becdab24d9a9b6a5594f076 (diff)
LazyInit: Implement Lazy Initialization by Delayed Module Entries
Lazy init is done by module entries which are delayed. Although visible in the module, the classes are only created when actually accessed by getattr. Internally, the access to the global Init_xxx functions is redirected to a Shiboken::Module::get function which resolves the classes if not already present in the global type array. PYSIDE6_OPTION_LAZY 0 - no lazy loading 1 - lazy load all known modules 2 - lazy load all modules Task-number: PYSIDE-2404 Change-Id: I98c01856e293732c166662050d0fbc6f6ec9082b Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/shiboken6/generator/shiboken/cppgenerator.cpp')
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp72
1 files changed, 50 insertions, 22 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 9bd6af7c1..55da21d8b 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -4182,6 +4182,8 @@ void CppGenerator::writeExtendedConverterInitialization(TextStream &s,
QString targetTypeName = fixedCppTypeName(externalType);
QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
+ if (!externalType->isPrimitive())
+ s << cpythonTypeNameExt(externalType) << ";\n";
writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
}
}
@@ -5236,7 +5238,7 @@ bool CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum
bool etypeUsed = false;
- QString enumVarTypeObj = cpythonTypeNameExt(enumTypeEntry);
+ QString enumVarTypeObj = cpythonTypeNameExtSet(enumTypeEntry);
if (!cppEnum.isAnonymous()) {
int packageLevel = packageName().count(u'.') + 1;
s << "EType = Shiboken::Enum::"
@@ -5250,7 +5252,7 @@ bool CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum
if (cppEnum.typeEntry()->flags()) {
s << "// PYSIDE-1735: Mapping the flags class to the same enum class.\n"
- << cpythonTypeNameExt(cppEnum.typeEntry()->flags()) << " =\n"
+ << cpythonTypeNameExtSet(cppEnum.typeEntry()->flags()) << " =\n"
<< indent << "EType;\n" << outdent;
}
writeEnumConverterInitialization(s, cppEnum);
@@ -5365,8 +5367,8 @@ void CppGenerator::writeClassRegister(TextStream &s,
// PYSIDE-510: Create a signatures string for the introspection feature.
writeSignatureStrings(s, signatures, initFunctionName, "functions");
- s << "void init_" << initFunctionName;
- s << "(PyObject *" << enclosingObjectVariable << ")\n{\n" << indent;
+ s << "PyTypeObject *init_" << initFunctionName
+ << "(PyObject *" << enclosingObjectVariable << ")\n{\n" << indent;
// Multiple inheritance
QString pyTypeBasesVariable = chopType(pyTypeName) + u"_Type_bases"_s;
@@ -5459,9 +5461,9 @@ void CppGenerator::writeClassRegister(TextStream &s,
<< chopType(pyTypeName) << "_PropertyStrings);\n";
if (!classContext.forSmartPointer())
- s << cpythonTypeNameExt(classTypeEntry) << " = pyType;\n\n";
+ s << cpythonTypeNameExtSet(classTypeEntry) << " = pyType;\n\n";
else
- s << cpythonTypeNameExt(classContext.preciseType()) << " = pyType;\n\n";
+ s << cpythonTypeNameExtSet(classContext.preciseType()) << " = pyType;\n\n";
// Register conversions for the type.
writeConverterRegister(s, metaClass, classContext);
@@ -5534,15 +5536,31 @@ void CppGenerator::writeClassRegister(TextStream &s,
<< "));\n";
}
- s << outdent << "}\n";
+ s << "\nreturn pyType;\n" << outdent << "}\n";
}
void CppGenerator::writeStaticFieldInitialization(TextStream &s,
const AbstractMetaClassCPtr &metaClass)
{
- s << "\nvoid " << getSimpleClassStaticFieldsInitFunctionName(metaClass)
- << "()\n{\n" << indent << "Shiboken::AutoDecRef dict(PepType_GetDict(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeName(metaClass) << ")));\n";
+ // cpythonTypeName == "Sbk_QRhiShaderResourceBinding_Data_TypeF"
+ QString name = cpythonTypeName(metaClass);
+ const auto parts = QStringView{name}.split(u'_', Qt::SkipEmptyParts);
+ if (parts.size() < 4) {
+ s << "\nPyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "(PyObject *module)\n{\n" << indent
+ << "auto *obType = PyObject_GetAttrString(module, \"" << metaClass->name() << "\");\n"
+ << "auto *type = reinterpret_cast<PyTypeObject *>(obType);\n"
+ << "Shiboken::AutoDecRef dict(PepType_GetDict(type));\n";
+ } else {
+ s << "\nPyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "(PyObject *module)\n{\n" << indent
+ << "auto *obContainerType = PyObject_GetAttrString(module, \""
+ << parts.at(1) << "\");\n"
+ << "auto *obType = PyObject_GetAttrString(obContainerType, \""
+ << parts.at(2) << "\");\n"
+ << "auto *type = reinterpret_cast<PyTypeObject *>(obType);\n"
+ << "Shiboken::AutoDecRef dict(PepType_GetDict(type));\n";
+ }
for (const AbstractMetaField &field : metaClass->fields()) {
if (field.isStatic()) {
s << "PyDict_SetItemString(dict, \"" << field.name()
@@ -5551,7 +5569,7 @@ void CppGenerator::writeStaticFieldInitialization(TextStream &s,
s << ");\n";
}
}
- s << '\n' << outdent << "}\n";
+ s << "return type;\n" << outdent << "}\n";
}
enum class QtRegisterMetaType
@@ -5873,18 +5891,28 @@ void CppGenerator::writeNbBoolFunction(const GeneratorContext &context,
// function.
void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr,
const QString &initFunctionName,
- const TypeEntryCPtr &enclosingEntry)
+ const TypeEntryCPtr &enclosingEntry,
+ const QString &pythonName)
{
const bool hasParent =
enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
- declStr << "void init_" << initFunctionName << "(PyObject *"
+ declStr << "PyTypeObject *init_" << initFunctionName << "(PyObject *"
<< (hasParent ? "enclosingClass" : "module") << ");\n";
- callStr << "init_" << initFunctionName;
if (hasParent) {
- callStr << "(reinterpret_cast<PyObject *>("
- << cpythonTypeNameExt(enclosingEntry) << "));\n";
+ const QString &enclosingName = enclosingEntry->name();
+ const auto parts = QStringView{enclosingName}.split(u"::", Qt::SkipEmptyParts);
+ callStr << "Shiboken::Module::AddTypeCreationFunction("
+ << "module, \"" << pythonName << "\", " << "init_" << initFunctionName << ", \"";
+ for (qsizetype i = 0; i < parts.size(); ++i) {
+ if (i > 0)
+ callStr << "\", \"";
+ callStr << parts.at(i);
+ }
+ callStr << "\");\n";
} else {
- callStr << "(module);\n";
+ callStr << "Shiboken::Module::AddTypeCreationFunction("
+ << "module, \"" << pythonName << "\", "
+ << "init_" << initFunctionName << ");\n";
}
}
@@ -5943,10 +5971,10 @@ bool CppGenerator::finishGeneration()
}
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getSimpleClassInitFunctionName(cls),
- targetLangEnclosingEntry(te));
+ targetLangEnclosingEntry(te), cls->name());
if (cls->hasStaticFields()) {
- s_classInitDecl << "void "
- << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ s_classInitDecl << "PyTypeObject *"
+ << getSimpleClassStaticFieldsInitFunctionName(cls) << "(PyObject *module);\n";
classesWithStaticFields.append(cls);
}
if (hasConfigCondition) {
@@ -5966,7 +5994,7 @@ bool CppGenerator::finishGeneration()
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getInitFunctionName(context),
- enclosingTypeEntry);
+ enclosingTypeEntry, smp.type.name());
includes.insert(smp.type.instantiations().constFirst().typeEntry()->include());
}
@@ -6304,7 +6332,7 @@ bool CppGenerator::finishGeneration()
s << "\n// Static field initialization\n";
for (const auto &cls : std::as_const(classesWithStaticFields)) {
ConfigurableScope configScope(s, cls->typeEntry());
- s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ s << getSimpleClassStaticFieldsInitFunctionName(cls) << "(module);\n";
}
}