diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-12-14 10:24:41 -0300 |
---|---|---|
committer | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-12-14 14:14:29 -0300 |
commit | cdcb5567c77b3f703541839101cad564605b7f61 (patch) | |
tree | ea3ad5751a0ab5f3a3b14bc6b85da82c019463d5 /libshiboken | |
parent | 0f31a28bcb0d802f461fd2012dd2a239decb81b0 (diff) |
All wrapped classes now inherit from the SbkBaseWrapper of the metatype SbkBaseWrapperType.
The wrapped classes are described with a SbkBaseWrapperType structure which
extends the PyTypeObject with information about multiple inheritance and
parenting ownership. This works well for the classes produced by the generator
but inheriting classes written in Python continues using the PyTypeObject to
describe themselves. To fix this the SbkBaseWrapperType is now a metatype for
all the wrapped classes and anyone inheriting from them.
In addition all the wrapped classes now inherit from SbkBaseWrapper, since
Python's PyType_Ready method need that multiple inheriting classes have a
common base class with the same size of the classes involved in the multiple
inheritance, which disqualifies Python's base "object" class.
The metatype and the base wrapper type are initialized by calling the new
Shiboken::init_shiboken() function. This is done by all the imported binding
modules, but it is really run only in the first call.
Another noteworthy change is the replacement of PyTypeObject as a basis for
SbkBaseWrapperType by the PyHeapTypeObject, since the latter is the proper
choice for types created on the heap, e.g. user defined classes extending
the generated wrapper classes.
Reviewed by Hugo Lima <hugo.lima@openbossa.org>
Diffstat (limited to 'libshiboken')
-rw-r--r-- | libshiboken/basewrapper.cpp | 163 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 13 | ||||
-rw-r--r-- | libshiboken/conversions.h | 2 |
3 files changed, 156 insertions, 22 deletions
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 397db1dff..eb7ee2b5d 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -41,12 +41,13 @@ namespace Shiboken void removeParent(SbkBaseWrapper* child) { - if (child->parentInfo->parent) { - ShiboChildrenList& oldBrothers = child->parentInfo->parent->parentInfo->children; - oldBrothers.remove(child); - child->parentInfo->parent = 0; - Py_DECREF(child); - } + if (!child->parentInfo->parent) + return; + + ShiboChildrenList& oldBrothers = child->parentInfo->parent->parentInfo->children; + oldBrothers.remove(child); + child->parentInfo->parent = 0; + Py_DECREF(child); } void setParent(PyObject* parent, PyObject* child) @@ -104,16 +105,18 @@ void destroyParentInfo(SbkBaseWrapper* obj, bool removeFromParent) _destroyParentInfo(obj, removeFromParent); } -PyObject* SbkBaseWrapper_New(PyTypeObject* instanceType, - const void* cptr, - unsigned int hasOwnership, - unsigned int containsCppWrapper) +PyObject* SbkBaseWrapper_New(SbkBaseWrapperType* instanceType, + const void* cptr, + unsigned int hasOwnership, + unsigned int containsCppWrapper) { + static PyObject* zeroargs = 0; if (!cptr) return 0; + else if (!zeroargs) + zeroargs = PyTuple_New(0); - SbkBaseWrapperType* const& instanceType_ = reinterpret_cast<SbkBaseWrapperType*>(instanceType); - SbkBaseWrapper* self = (SbkBaseWrapper*)instanceType_->pytype.tp_alloc((PyTypeObject*) instanceType, 0); + SbkBaseWrapper* self = reinterpret_cast<SbkBaseWrapper*>(PyBaseObject_Type.tp_new(reinterpret_cast<PyTypeObject*>(instanceType), zeroargs, 0)); self->cptr = const_cast<void*>(cptr); self->hasOwnership = hasOwnership; @@ -121,11 +124,11 @@ PyObject* SbkBaseWrapper_New(PyTypeObject* instanceType, self->validCppObject = 1; self->parentInfo = 0; - if (instanceType_->mi_init && !instanceType_->mi_offsets) - instanceType_->mi_offsets = instanceType_->mi_init(cptr); + if (instanceType->mi_init && !instanceType->mi_offsets) + instanceType->mi_offsets = instanceType->mi_init(cptr); BindingManager::instance().assignWrapper(reinterpret_cast<PyObject*>(self), cptr); - if (instanceType_->mi_offsets) { - int* offset = instanceType_->mi_offsets; + if (instanceType->mi_offsets) { + int* offset = instanceType->mi_offsets; while (*offset != -1) { if (*offset > 0) { BindingManager::instance().assignWrapper(reinterpret_cast<PyObject*>(self), @@ -148,8 +151,134 @@ bool cppObjectIsInvalid(PyObject* wrapper) void SbkBaseWrapper_Dealloc_PrivateDtor(PyObject* self) { BindingManager::instance().releaseWrapper(self); - Py_TYPE(((SbkBaseWrapper*)self))->tp_free((PyObject*)self); + Py_TYPE(reinterpret_cast<SbkBaseWrapper*>(self))->tp_free(self); } +// Wrapper metatype and base type ---------------------------------------------------------- + +extern "C" +{ + +struct SbkBaseWrapperType_Type; + +PyTypeObject SbkBaseWrapperType_Type = { + PyObject_HEAD_INIT(0) + /*ob_size*/ 0, + /*tp_name*/ "Shiboken.BaseWrapperType", + /*tp_basicsize*/ sizeof(SbkBaseWrapperType), + /*tp_itemsize*/ 0, + /*tp_dealloc*/ 0, + /*tp_print*/ 0, + /*tp_getattr*/ 0, + /*tp_setattr*/ 0, + /*tp_compare*/ 0, + /*tp_repr*/ 0, + /*tp_as_number*/ 0, + /*tp_as_sequence*/ 0, + /*tp_as_mapping*/ 0, + /*tp_hash*/ 0, + /*tp_call*/ 0, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + /*tp_doc*/ 0, + /*tp_traverse*/ 0, + /*tp_clear*/ 0, + /*tp_richcompare*/ 0, + /*tp_weaklistoffset*/ 0, + /*tp_iter*/ 0, + /*tp_iternext*/ 0, + /*tp_methods*/ 0, + /*tp_members*/ 0, + /*tp_getset*/ 0, + /*tp_base*/ 0, + /*tp_dict*/ 0, + /*tp_descr_get*/ 0, + /*tp_descr_set*/ 0, + /*tp_dictoffset*/ 0, + /*tp_init*/ 0, + /*tp_alloc*/ 0, + /*tp_new*/ 0, + /*tp_free*/ 0, + /*tp_is_gc*/ 0, + /*tp_bases*/ 0, + /*tp_mro*/ 0, + /*tp_cache*/ 0, + /*tp_subclasses*/ 0, + /*tp_weaklist*/ 0 +}; + +SbkBaseWrapperType SbkBaseWrapper_Type = { + PyObject_HEAD_INIT(&SbkBaseWrapperType_Type) + /*ob_size*/ 0, + /*tp_name*/ "Shiboken.BaseWrapper", + /*tp_basicsize*/ sizeof(SbkBaseWrapper), + /*tp_itemsize*/ 0, + /*tp_dealloc*/ 0, + /*tp_print*/ 0, + /*tp_getattr*/ 0, + /*tp_setattr*/ 0, + /*tp_compare*/ 0, + /*tp_repr*/ 0, + /*tp_as_number*/ 0, + /*tp_as_sequence*/ 0, + /*tp_as_mapping*/ 0, + /*tp_hash*/ 0, + /*tp_call*/ 0, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + /*tp_doc*/ 0, + /*tp_traverse*/ 0, + /*tp_clear*/ 0, + /*tp_richcompare*/ 0, + /*tp_weaklistoffset*/ 0, + /*tp_iter*/ 0, + /*tp_iternext*/ 0, + /*tp_methods*/ 0, + /*tp_members*/ 0, + /*tp_getset*/ 0, + /*tp_base*/ 0, + /*tp_dict*/ 0, + /*tp_descr_get*/ 0, + /*tp_descr_set*/ 0, + /*tp_dictoffset*/ 0, + /*tp_init*/ 0, + /*tp_alloc*/ 0, + /*tp_new*/ 0, + /*tp_free*/ 0, + /*tp_is_gc*/ 0, + /*tp_bases*/ 0, + /*tp_mro*/ 0, + /*tp_cache*/ 0, + /*tp_subclasses*/ 0, + /*tp_weaklist*/ 0 +}; + +PyAPI_FUNC(void) init_shiboken() +{ + static bool shibokenAlreadInitialised = false; + if (shibokenAlreadInitialised) + return; + + SbkBaseWrapperType_Type.tp_base = &PyType_Type; + + if (PyType_Ready(&SbkBaseWrapperType_Type) < 0) + Py_FatalError("[libshiboken] Failed to initialise Shiboken.BaseWrapperType metatype."); + + if (PyType_Ready((PyTypeObject *)&SbkBaseWrapper_Type) < 0) + Py_FatalError("[libshiboken] Failed to initialise Shiboken.BaseWrapper type."); + + shibokenAlreadInitialised = true; +} + +} // extern "C" + } // namespace Shiboken + + diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index 46471e5ed..5f781d547 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -70,10 +70,13 @@ struct SbkBaseWrapperType; */ typedef void* (*SpecialCastFunction)(PyObject*, SbkBaseWrapperType*); +LIBSHIBOKEN_API PyAPI_DATA(PyTypeObject) SbkBaseWrapperType_Type; +LIBSHIBOKEN_API PyAPI_DATA(SbkBaseWrapperType) SbkBaseWrapper_Type; + /// PyTypeObject extended with C++ multiple inheritance information. struct LIBSHIBOKEN_API SbkBaseWrapperType { - PyTypeObject pytype; + PyHeapTypeObject super; int* mi_offsets; MultipleInheritanceInitFunction mi_init; /// Special cast function, null if this class doesn't have multiple inheritance. @@ -96,6 +99,8 @@ struct LIBSHIBOKEN_API SbkBaseWrapper ShiboParentInfo* parentInfo; }; +LIBSHIBOKEN_API PyAPI_FUNC(void) init_shiboken(); + } // extern "C" /** @@ -186,7 +191,7 @@ typedef struct { #endif LIBSHIBOKEN_API PyAPI_FUNC(PyObject*) -SbkBaseWrapper_New(PyTypeObject* instanceType, +SbkBaseWrapper_New(SbkBaseWrapperType* instanceType, const void *cptr, unsigned int hasOwnership = 1, unsigned int containsCppWrapper = 0); @@ -199,10 +204,10 @@ void SbkBaseWrapper_Dealloc(PyObject* self) { BindingManager::instance().releaseWrapper(self); if (SbkBaseWrapper_hasOwnership(self)) - delete ((T*)SbkBaseWrapper_cptr(self)); + delete (reinterpret_cast<T*>(SbkBaseWrapper_cptr(self))); if (SbkBaseWrapper_hasParentInfo(self)) destroyParentInfo(reinterpret_cast<SbkBaseWrapper*>(self)); - Py_TYPE(((SbkBaseWrapper*)self))->tp_free((PyObject*)self); + Py_TYPE(reinterpret_cast<SbkBaseWrapper*>(self))->tp_free(self); } LIBSHIBOKEN_API PyAPI_FUNC(void) SbkBaseWrapper_Dealloc_PrivateDtor(PyObject* self); diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index 7b911b3ea..301a27212 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -79,7 +79,7 @@ struct ConverterBase { static PyObject* createWrapper(const T* cppobj) { - return Shiboken::SbkBaseWrapper_New(SbkType<T>(), cppobj); + return Shiboken::SbkBaseWrapper_New(reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>()), cppobj); } static bool isConvertible(PyObject* pyobj) { return pyobj == Py_None; } |