aboutsummaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
authorPankaj Pandey <pankaj86@gmail.com>2014-05-27 12:21:39 +0530
committerChristian Tismer <tismer@stackless.com>2017-03-17 15:44:14 +0000
commit8d99ee1f6af693ad45dcd03fcae6a86f8f86302a (patch)
tree038c1d01357af5418fcc4947a7d60153e0d3aa5a /generator
parent4d76c6e2c9870ce3928425682e7f091396592206 (diff)
Improve the 'Value' type wrapper registration
This commit works around some bugs where multiple/incorrect wrappers were registered for some types: - In cases where the first field of a class was itself a Value type instance (instead of pointer), both the parent and child wrappers had same cptr address, causing confusion in retrieveWrapper. Previously, this was worked around by always creating a new wrapper for all Value type fields on every access, causing leaks. We now check for colocated child wrappers and return that instead of creating new wrapper, so each Value type subfield need only have one wrapper. - Some cases of incorrect wrapper registration due to an existing wrapper which shiboken could not figure being deleted are fixed, specifically cases where the newly registered wrapper is from object created in python or owns its wrapper. - Do not release incorrect wrapper in case of address reuse by checking that the registered wrapper is indeed the wrapper being released. Task-number: PYSIDE-217 Task-number: PYSIDE-224 Change-Id: I019c078566c4b9b90e63c5d991e2e372d39c632a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'generator')
-rw-r--r--generator/shiboken2/cppgenerator.cpp36
1 files changed, 35 insertions, 1 deletions
diff --git a/generator/shiboken2/cppgenerator.cpp b/generator/shiboken2/cppgenerator.cpp
index c8e919c..f0c2fe4 100644
--- a/generator/shiboken2/cppgenerator.cpp
+++ b/generator/shiboken2/cppgenerator.cpp
@@ -1577,6 +1577,14 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// Python owns it and C++ wrapper is false.
if (shouldGenerateCppWrapper(overloads.first()->ownerClass()))
s << INDENT << "Shiboken::Object::setHasCppWrapper(sbkSelf, true);" << endl;
+ // Need to check if a wrapper for same pointer is already registered
+ // Caused by bug PYSIDE-217, where deleted objects' wrappers are not released
+ s << INDENT << "if (Shiboken::BindingManager::instance().hasWrapper(cptr)) {" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "Shiboken::BindingManager::instance().releaseWrapper(Shiboken::BindingManager::instance().retrieveWrapper(cptr));" << endl;
+ }
+ s << INDENT << "}" << endl;
s << INDENT << "Shiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);" << endl;
// Create metaObject and register signal/slot
@@ -4011,12 +4019,38 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
cppField = QLatin1String("fieldValue");
}
- s << INDENT << "PyObject* pyOut = ";
+ s << INDENT << "PyObject* pyOut = 0;\n";
if (newWrapperSameObject) {
+ // Special case colocated field with same address (first field in a struct)
+ s << INDENT << "if (reinterpret_cast<void *>("
+ << cppField
+ << ") == reinterpret_cast<void *>("
+ << CPP_SELF_VAR << ")) {\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "pyOut = (PyObject*)Shiboken::Object::findColocatedChild("
+ << "(SbkObject*)self , (SbkObjectType*)"
+ << cpythonTypeNameExt(fieldType)
+ << ");" << "\n";
+ s << INDENT << "if (pyOut) {Py_IncRef(pyOut); return pyOut;}\n";
+ }
+ s << INDENT << "}\n";
+ // Check if field wrapper has already been created.
+ s << INDENT << "else if (Shiboken::BindingManager::instance().hasWrapper(" << cppField << ")) {" << "\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "pyOut = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(" << cppField << ");" << "\n";
+ s << INDENT << "Py_IncRef(pyOut);" << "\n";
+ s << INDENT << "return pyOut;" << "\n";
+ }
+ s << INDENT << "}\n";
+ // Create and register new wrapper
+ s << INDENT << "pyOut = ";
s << "Shiboken::Object::newObject((SbkObjectType*)" << cpythonTypeNameExt(fieldType);
s << ", " << cppField << ", false, true);" << endl;
s << INDENT << "Shiboken::Object::setParent(" PYTHON_SELF_VAR ", pyOut)";
} else {
+ s << INDENT << "pyOut = ";
writeToPythonConversion(s, fieldType, metaField->enclosingClass(), cppField);
}
s << ';' << endl;