From 5316ff58e5c527360d22cd43328990da10ce4ec7 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Tue, 9 Feb 2010 15:36:30 -0300 Subject: Adds support to arguments marked as keep reference in the type system. Every method marked to increment the reference count of any argument must decrement the reference count of previously held objects. A dictionary is used to associate the method overload and Python wrapper instance with the previously set object. --- cppgenerator.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 543034ed6..49fb4f2ed 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -184,6 +184,18 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << "using namespace Shiboken;" << endl << endl; + // If the class has any method with "reference-count" modifications + // the support system will need C++ STL's pair and map. + if (hasMethodsWithReferenceCountModifications(metaClass)) { + s << "#include " << endl; + s << "#include " << endl; + s << "using std::make_pair;" << endl; + s << "typedef std::pair SbkRefCountKey;" << endl; + s << "typedef std::map SbkRefCountMap;" << endl; + s << "static SbkRefCountMap sbk_refcount_map;" << endl; + s << endl; + } + // class inject-code native/beginning if (!metaClass->typeEntry()->codeSnips().isEmpty()) { writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Beginning, TypeSystem::NativeCode, 0, 0, metaClass); @@ -1496,10 +1508,14 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f // Ownership transference between C++ and Python. QList ownership_mods; + // Python object reference management. + QList refcount_mods; foreach (FunctionModification func_mod, func->modifications()) { foreach (ArgumentModification arg_mod, func_mod.argument_mods) { if (!arg_mod.ownerships.isEmpty() && arg_mod.ownerships.contains(TypeSystem::TargetLangCode)) ownership_mods.append(arg_mod); + else if (!arg_mod.referenceCounts.isEmpty()) + refcount_mods.append(arg_mod); } } @@ -1527,6 +1543,28 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f } s << endl; } + + } else if (!refcount_mods.isEmpty()) { + foreach (ArgumentModification arg_mod, refcount_mods) { + if (arg_mod.referenceCounts.first().action != ReferenceCount::Add) + continue; + const AbstractMetaClass* wrappedClass = 0; + QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass); + if (!wrappedClass) { + s << "#error Invalid reference count modification for argument " << arg_mod.index << endl << endl; + break; + } + + s << INDENT << "SbkRefCountKey sbk_refcount_key = make_pair(self, \"" << func->minimalSignature() << "\");" << endl; + s << INDENT << "SbkRefCountMap::iterator sbk_refcount_iter = sbk_refcount_map.find(sbk_refcount_key);" << endl; + s << INDENT << "if (sbk_refcount_iter != sbk_refcount_map.end())" << endl; + { + Indentation indent(INDENT); + s << INDENT << "Py_XDECREF(sbk_refcount_iter->second);" << endl; + } + s << INDENT << "Py_INCREF(" << pyArgName << ");" << endl; + s << INDENT << "sbk_refcount_map[sbk_refcount_key] = " << pyArgName << ';' << endl; + } } } -- cgit v1.2.3