diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-11-10 11:42:46 -0200 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:08:57 -0300 |
commit | 4c0e03c6fefefd75c270b2b47eb0d240301ade0e (patch) | |
tree | 937d41e0ede39b1cfdaef4a1524c5ff7912b7716 /libshiboken | |
parent | 4de6fd579daeb965871713d1da0625bd684758c3 (diff) |
SbkBaseWrapperType and some other functions used by Python C-API moved outside C++ namespaces.
Diffstat (limited to 'libshiboken')
-rw-r--r-- | libshiboken/basewrapper.cpp | 266 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 43 | ||||
-rw-r--r-- | libshiboken/basewrapper_p.h | 13 | ||||
-rw-r--r-- | libshiboken/bindingmanager.cpp | 4 | ||||
-rw-r--r-- | libshiboken/bindingmanager.h | 3 | ||||
-rw-r--r-- | libshiboken/conversions.h | 2 | ||||
-rw-r--r-- | libshiboken/typeresolver.h | 4 |
7 files changed, 167 insertions, 168 deletions
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 5c0c3c210..5de9024e5 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -30,16 +30,11 @@ #include <string> #include <cstring> -namespace Shiboken +extern "C" { static void SbkBaseWrapperType_dealloc(PyObject* pyObj); static PyObject* SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds); -static void incRefPyObject(PyObject* pyObj); -static void decRefPyObjectList(const std::list<SbkObject*> &pyObj); - -extern "C" -{ PyTypeObject SbkBaseWrapperType_Type = { PyObject_HEAD_INIT(0) @@ -111,7 +106,7 @@ SbkBaseWrapperType SbkBaseWrapper_Type = { { { /*tp_name*/ "Shiboken.BaseWrapper", /*tp_basicsize*/ sizeof(SbkObject), /*tp_itemsize*/ 0, - /*tp_dealloc*/ deallocWrapperWithPrivateDtor, + /*tp_dealloc*/ SbkDeallocWrapperWithPrivateDtor, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, @@ -161,8 +156,105 @@ SbkBaseWrapperType SbkBaseWrapper_Type = { { { /*ext_tocpp*/ 0 }; + +void SbkDeallocWrapper(PyObject* pyObj) +{ + SbkObject* sbkObj = reinterpret_cast<SbkObject*>(pyObj); + if (sbkObj->weakreflist) + PyObject_ClearWeakRefs(pyObj); + + Shiboken::BindingManager::instance().releaseWrapper(sbkObj); + if (sbkObj->d->hasOwnership) { + SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type); + if (sbkType->is_multicpp) { + Shiboken::DtorCallerVisitor visitor(sbkObj); + Shiboken::walkThroughClassHierarchy(pyObj->ob_type, &visitor); + } else { + sbkType->cpp_dtor(sbkObj->d->cptr[0]); + } + } + + if (sbkObj->d->parentInfo) + Shiboken::destroyParentInfo(sbkObj); + + Shiboken::clearReferences(sbkObj); + + Py_XDECREF(sbkObj->ob_dict); + delete[] sbkObj->d->cptr; + sbkObj->d->cptr = 0; + delete sbkObj->d; + Py_TYPE(pyObj)->tp_free(pyObj); +} + +void SbkDeallocWrapperWithPrivateDtor(PyObject* self) +{ + if (((SbkObject *)self)->weakreflist) + PyObject_ClearWeakRefs(self); + + Shiboken::BindingManager::instance().releaseWrapper(reinterpret_cast<SbkObject*>(self)); + Shiboken::clearReferences(reinterpret_cast<SbkObject*>(self)); + self->ob_type->tp_free(self); +} + +void SbkBaseWrapperType_dealloc(PyObject* pyObj) +{ + SbkBaseWrapperType *sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type); + + if(sbkType->user_data && sbkType->d_func) { + sbkType->d_func(sbkType->user_data); + sbkType->user_data = 0; + } +} + +PyObject* SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) +{ + // The meta type creates a new type when the Python programmer extends a wrapped C++ class. + SbkBaseWrapperType* newType = reinterpret_cast<SbkBaseWrapperType*>(PyType_Type.tp_new(metatype, args, kwds)); + + if (!newType) + return 0; + + std::list<SbkBaseWrapperType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); + if (bases.size() == 1) { + SbkBaseWrapperType* parentType = bases.front(); + newType->mi_offsets = parentType->mi_offsets; + newType->mi_init = parentType->mi_init; + newType->mi_specialcast = parentType->mi_specialcast; + newType->ext_isconvertible = parentType->ext_isconvertible; + newType->ext_tocpp = parentType->ext_tocpp; + newType->type_discovery = parentType->type_discovery; + newType->obj_copier = parentType->obj_copier; + newType->cpp_dtor = parentType->cpp_dtor; + newType->is_multicpp = 0; + } else { + newType->mi_offsets = 0; + newType->mi_init = 0; + newType->mi_specialcast = 0; + newType->ext_isconvertible = 0; + newType->ext_tocpp = 0; + newType->type_discovery = 0; + newType->obj_copier = 0; + newType->cpp_dtor = 0; + newType->is_multicpp = 1; + } + if (bases.size() == 1) + newType->original_name = bases.front()->original_name; + else + newType->original_name = "object"; + newType->user_data = 0; + newType->d_func = 0; + newType->is_user_type = 1; + return reinterpret_cast<PyObject*>(newType); +} + } //extern "C" +namespace Shiboken +{ + +static void incRefPyObject(PyObject* pyObj); +static void decRefPyObjectList(const std::list<SbkObject*> &pyObj); + void removeParent(SbkObject* child) { ParentInfo* pInfo = child->d->parentInfo; @@ -268,31 +360,6 @@ void destroyParentInfo(SbkObject* obj, bool removeFromParent) _destroyParentInfo(obj, removeFromParent); } -PyObject* SbkBaseWrapper_New(SbkBaseWrapperType* instanceType, - void* cptr, - bool hasOwnership, - bool isExactType, const char* typeName) -{ - // Try to find the exact type of cptr. - if (!isExactType) { - TypeResolver* tr = 0; - if (typeName) { - tr = TypeResolver::get(typeName); - if (tr) - instanceType = reinterpret_cast<SbkBaseWrapperType*>(tr->pythonType()); - } - if (!tr) - instanceType = BindingManager::instance().resolveType(cptr, instanceType); - } - - SbkObject* self = reinterpret_cast<SbkObject*>(SbkBaseWrapper_TpNew(reinterpret_cast<PyTypeObject*>(instanceType), 0, 0)); - self->d->cptr[0] = cptr; - self->d->hasOwnership = hasOwnership; - self->d->validCppObject = 1; - BindingManager::instance().registerWrapper(self, cptr); - return reinterpret_cast<PyObject*>(self); -} - void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) { PyObject* bases = currentType->tp_bases; @@ -300,7 +367,7 @@ void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visi for (int i = 0; i < numBases; ++i) { PyTypeObject* type = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i)); - if (type->ob_type != &Shiboken::SbkBaseWrapperType_Type) { + if (type->ob_type != &SbkBaseWrapperType_Type) { continue; } else { SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(type); @@ -348,16 +415,6 @@ void* getTypeUserData(SbkObject* wrapper) return reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type)->user_data; } -void deallocWrapperWithPrivateDtor(PyObject* self) -{ - if (((SbkObject *)self)->weakreflist) - PyObject_ClearWeakRefs(self); - - BindingManager::instance().releaseWrapper(reinterpret_cast<SbkObject*>(self)); - clearReferences(reinterpret_cast<SbkObject*>(self)); - self->ob_type->tp_free(self); -} - void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append) { @@ -416,99 +473,10 @@ bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr) // Wrapper metatype and base type ---------------------------------------------------------- -class DtorCallerVisitor : public HierarchyVisitor -{ -public: - DtorCallerVisitor(SbkObject* pyObj) : m_count(0), m_pyObj(pyObj) {} - virtual void visit(SbkBaseWrapperType* node) - { - node->cpp_dtor(m_pyObj->d->cptr[m_count]); - m_count++; - } -private: - int m_count; - SbkObject* m_pyObj; -}; - -void deallocWrapper(PyObject* pyObj) +void DtorCallerVisitor::visit(SbkBaseWrapperType* node) { - SbkObject* sbkObj = reinterpret_cast<SbkObject*>(pyObj); - if (sbkObj->weakreflist) - PyObject_ClearWeakRefs(pyObj); - - BindingManager::instance().releaseWrapper(sbkObj); - if (sbkObj->d->hasOwnership) { - SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type); - if (sbkType->is_multicpp) { - DtorCallerVisitor visitor(sbkObj); - walkThroughClassHierarchy(pyObj->ob_type, &visitor); - } else { - sbkType->cpp_dtor(sbkObj->d->cptr[0]); - } - } - - if (sbkObj->d->parentInfo) - destroyParentInfo(sbkObj); - - clearReferences(sbkObj); - - Py_XDECREF(sbkObj->ob_dict); - delete[] sbkObj->d->cptr; - sbkObj->d->cptr = 0; - delete sbkObj->d; - Py_TYPE(pyObj)->tp_free(pyObj); - -} - -void SbkBaseWrapperType_dealloc(PyObject* pyObj) -{ - SbkBaseWrapperType *sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type); - - if(sbkType->user_data && sbkType->d_func) { - sbkType->d_func(sbkType->user_data); - sbkType->user_data = 0; - } -} - -PyObject* SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds) -{ - // The meta type creates a new type when the Python programmer extends a wrapped C++ class. - SbkBaseWrapperType* newType = reinterpret_cast<SbkBaseWrapperType*>(PyType_Type.tp_new(metatype, args, kwds)); - - if (!newType) - return 0; - - std::list<SbkBaseWrapperType*> bases = getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType)); - if (bases.size() == 1) { - SbkBaseWrapperType* parentType = bases.front(); - newType->mi_offsets = parentType->mi_offsets; - newType->mi_init = parentType->mi_init; - newType->mi_specialcast = parentType->mi_specialcast; - newType->ext_isconvertible = parentType->ext_isconvertible; - newType->ext_tocpp = parentType->ext_tocpp; - newType->type_discovery = parentType->type_discovery; - newType->obj_copier = parentType->obj_copier; - newType->cpp_dtor = parentType->cpp_dtor; - newType->is_multicpp = 0; - } else { - newType->mi_offsets = 0; - newType->mi_init = 0; - newType->mi_specialcast = 0; - newType->ext_isconvertible = 0; - newType->ext_tocpp = 0; - newType->type_discovery = 0; - newType->obj_copier = 0; - newType->cpp_dtor = 0; - newType->is_multicpp = 1; - } - if (bases.size() == 1) - newType->original_name = bases.front()->original_name; - else - newType->original_name = "object"; - newType->user_data = 0; - newType->d_func = 0; - newType->is_user_type = 1; - return reinterpret_cast<PyObject*>(newType); + node->cpp_dtor(m_pyObj->d->cptr[m_count]); + m_count++; } void initShiboken() @@ -720,7 +688,7 @@ bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr) bool isValid(PyObject* pyObj) { if (!pyObj || pyObj == Py_None - || pyObj->ob_type->ob_type != &Shiboken::SbkBaseWrapperType_Type + || pyObj->ob_type->ob_type != &SbkBaseWrapperType_Type || ((SbkObject*)pyObj)->d->validCppObject) { return true; } @@ -728,6 +696,32 @@ bool isValid(PyObject* pyObj) return false; } +PyObject* newObject(SbkBaseWrapperType* instanceType, + void* cptr, + bool hasOwnership, + bool isExactType, + const char* typeName) +{ + // Try to find the exact type of cptr. + if (!isExactType) { + TypeResolver* tr = 0; + if (typeName) { + tr = TypeResolver::get(typeName); + if (tr) + instanceType = reinterpret_cast<SbkBaseWrapperType*>(tr->pythonType()); + } + if (!tr) + instanceType = BindingManager::instance().resolveType(cptr, instanceType); + } + + SbkObject* self = reinterpret_cast<SbkObject*>(SbkBaseWrapper_TpNew(reinterpret_cast<PyTypeObject*>(instanceType), 0, 0)); + self->d->cptr[0] = cptr; + self->d->hasOwnership = hasOwnership; + self->d->validCppObject = 1; + BindingManager::instance().registerWrapper(self, cptr); + return reinterpret_cast<PyObject*>(self); +} + } // namespace Wrapper } // namespace Shiboken diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index d8511dd82..9702992ab 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -46,22 +46,21 @@ struct LIBSHIBOKEN_API SbkObject SbkBaseWrapperPrivate* d; }; -} -namespace Shiboken -{ +/// Dealloc the python object \p pyObj and the C++ object represented by it. +LIBSHIBOKEN_API void SbkDeallocWrapper(PyObject* pyObj); +LIBSHIBOKEN_API void SbkDeallocWrapperWithPrivateDtor(PyObject* self); + +struct SbkBaseWrapperType; -extern "C" -{ /// Function signature for the multiple inheritance information initializers that should be provided by classes with multiple inheritance. typedef int* (*MultipleInheritanceInitFunction)(const void*); -struct SbkBaseWrapperType; /** -* Special cast function is used to correctly cast an object when it's -* part of a multiple inheritance hierarchy. -* The implementation of this function is auto generated by the generator and you don't need to care about it. -*/ + * Special cast function is used to correctly cast an object when it's + * part of a multiple inheritance hierarchy. + * The implementation of this function is auto generated by the generator and you don't need to care about it. + */ typedef void* (*SpecialCastFunction)(void*, SbkBaseWrapperType*); typedef void* (*ObjectCopierFunction)(const void*); typedef SbkBaseWrapperType* (*TypeDiscoveryFunc)(void*, SbkBaseWrapperType*); @@ -104,6 +103,9 @@ struct LIBSHIBOKEN_API SbkBaseWrapperType } // extern "C" +namespace Shiboken +{ + /** * Init shiboken library. */ @@ -162,15 +164,8 @@ LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctor */ #define Shiboken_TypeCheck(pyobj, type) (PyObject_TypeCheck(pyobj, SbkType<type>())) -#define SbkBaseWrapper_Check(op) PyObject_TypeCheck(op, (PyTypeObject*)&Shiboken::SbkBaseWrapper_Type) -#define SbkBaseWrapper_CheckExact(op) ((op)->ob_type == &Shiboken::SbkBaseWrapper_Type) - -LIBSHIBOKEN_API PyObject* -SbkBaseWrapper_New(SbkBaseWrapperType* instanceType, - void* cptr, - bool hasOwnership = true, - bool isExactType = false, - const char* typeName = 0); +#define SbkBaseWrapper_Check(op) PyObject_TypeCheck(op, (PyTypeObject*)&SbkBaseWrapper_Type) +#define SbkBaseWrapper_CheckExact(op) ((op)->ob_type == &SbkBaseWrapper_Type) LIBSHIBOKEN_API PyObject* SbkBaseWrapper_TpNew(PyTypeObject* subtype, PyObject*, PyObject*); @@ -189,9 +184,6 @@ SbkBaseWrapper_TpNew(PyTypeObject* subtype, PyObject*, PyObject*); */ LIBSHIBOKEN_API void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append=false); -/// Dealloc the python object \p pyObj and the C++ object represented by it. -LIBSHIBOKEN_API void deallocWrapper(PyObject* pyObj); - /// Delete the class T allocated on \p cptr. template<typename T> void callCppDestructor(void* cptr) @@ -199,12 +191,17 @@ void callCppDestructor(void* cptr) delete reinterpret_cast<T*>(cptr); } -LIBSHIBOKEN_API void deallocWrapperWithPrivateDtor(PyObject* self); LIBSHIBOKEN_API bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr); LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const char** cppOverloads); namespace Wrapper { +LIBSHIBOKEN_API PyObject* newObject(SbkBaseWrapperType* instanceType, + void* cptr, + bool hasOwnership = true, + bool isExactType = false, + const char* typeName = 0); + LIBSHIBOKEN_API void setValidCpp(SbkObject* pyObj, bool value); LIBSHIBOKEN_API void setHasCppWrapper(SbkObject* pyObj, bool value); LIBSHIBOKEN_API bool hasCppWrapper(SbkObject* pyObj); diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index 34a3ea6d5..6b8b9ab34 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -28,6 +28,7 @@ #include <map> struct SbkObject; +struct SbkBaseWrapperType; namespace Shiboken { @@ -88,8 +89,6 @@ namespace Shiboken **/ std::list<SbkObject*> splitPyObject(PyObject* pyObj); -struct SbkBaseWrapperType; - /** * Visitor class used by walkOnClassHierarchy function. */ @@ -152,6 +151,16 @@ private: PyTypeObject* m_desiredType; }; +class DtorCallerVisitor : public HierarchyVisitor +{ +public: + DtorCallerVisitor(SbkObject* pyObj) : m_count(0), m_pyObj(pyObj) {} + void visit(SbkBaseWrapperType* node); +private: + int m_count; + SbkObject* m_pyObj; +}; + /// \internal Internal function used to walk on classes inheritance trees. /** * Walk on class hierarchy using a DFS algorithm. diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp index e667f6173..5e0cbf3df 100644 --- a/libshiboken/bindingmanager.cpp +++ b/libshiboken/bindingmanager.cpp @@ -333,12 +333,12 @@ void BindingManager::transferOwnershipToCpp(SbkObject* wrapper) invalidateWrapper(wrapper); } -void BindingManager::addClassInheritance(Shiboken::SbkBaseWrapperType* parent, Shiboken::SbkBaseWrapperType* child) +void BindingManager::addClassInheritance(SbkBaseWrapperType* parent, SbkBaseWrapperType* child) { m_d->classHierarchy.addEdge(parent, child); } -SbkBaseWrapperType* BindingManager::resolveType(void* cptr, Shiboken::SbkBaseWrapperType* type) +SbkBaseWrapperType* BindingManager::resolveType(void* cptr, SbkBaseWrapperType* type) { SbkBaseWrapperType* identifiedType = m_d->classHierarchy.identifyType(cptr, type, type); return identifiedType ? identifiedType : type; diff --git a/libshiboken/bindingmanager.h b/libshiboken/bindingmanager.h index 910e6053e..8a6607fd4 100644 --- a/libshiboken/bindingmanager.h +++ b/libshiboken/bindingmanager.h @@ -28,12 +28,11 @@ #include "shibokenmacros.h" struct SbkObject; +struct SbkBaseWrapperType; namespace Shiboken { -struct SbkBaseWrapperType; - class LIBSHIBOKEN_API BindingManager { public: diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index 4cead3439..a590ea193 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -113,7 +113,7 @@ inline PyObject* createWrapper(const T* cppobj, bool hasOwnership = false, bool const char* typeName = 0; if (!isExactType) typeName = typeid(*const_cast<T*>(cppobj)).name(); - return SbkBaseWrapper_New(reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>()), + return Wrapper::newObject(reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>()), const_cast<T*>(cppobj), hasOwnership, isExactType, typeName); } diff --git a/libshiboken/typeresolver.h b/libshiboken/typeresolver.h index b11678e2b..4e23b970d 100644 --- a/libshiboken/typeresolver.h +++ b/libshiboken/typeresolver.h @@ -26,11 +26,11 @@ #include "shibokenmacros.h" #include "conversions.h" +class SbkBaseWrapperType; + namespace Shiboken { -class SbkBaseWrapperType; - /* To C++ convertion functions. */ template <typename T> inline void* pythonToValueType(PyObject* pyobj, void** data, bool alloc) |