diff options
Diffstat (limited to 'lib/python')
| -rw-r--r-- | lib/python/connections.cpp | 26 | ||||
| -rw-r--r-- | lib/python/connections.h | 38 | ||||
| -rw-r--r-- | lib/python/python.cpp | 156 | ||||
| -rw-r--r-- | lib/python/python.h | 227 | ||||
| -rw-r--r-- | lib/python/swig.h | 2 |
5 files changed, 352 insertions, 97 deletions
diff --git a/lib/python/connections.cpp b/lib/python/connections.cpp index c24c9399..fd3e2a4b 100644 --- a/lib/python/connections.cpp +++ b/lib/python/connections.cpp @@ -1,9 +1,29 @@ #include <lib/python/connections.h> -PSignal1<void,int> testsignal; +PSignal::PSignal() +{ + m_list = PyList_New(0); + Py_INCREF(m_list); +} -void connect(Slot1<void, int> &slot, PyObject *fnc) +PSignal::~PSignal() { - printf("CONNECT !\n"); + Py_DECREF(m_list); } +void PSignal::callPython(ePyObject tuple) +{ + int size = PyList_Size(m_list); + int i; + for (i=0; i<size; ++i) + { + ePyObject b = PyList_GET_ITEM(m_list, i); + ePython::call(b, tuple); + } +} + +PyObject *PSignal::get() +{ + Py_INCREF(m_list); + return m_list; +} diff --git a/lib/python/connections.h b/lib/python/connections.h index 8a06f7fa..d24bb42f 100644 --- a/lib/python/connections.h +++ b/lib/python/connections.h @@ -7,37 +7,17 @@ #include <features.h> #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L -#include <Python.h> + #include <lib/python/python.h> class PSignal { + ePyObject m_list; public: - PyObject *m_list; -public: - PSignal() - { - m_list = PyList_New(0); - Py_INCREF(m_list); - } - ~PSignal() - { - Py_DECREF(m_list); - } - - void callPython(PyObject *tuple) - { - int size = PyList_Size(m_list); - int i; - for (i=0; i<size; ++i) - { - PyObject *b = PyList_GET_ITEM(m_list, i); - ePython::call(b, tuple); - } - } - - - PyObject *get() { Py_INCREF(m_list); return m_list; } + PSignal(); + ~PSignal(); + void callPython(SWIG_PYOBJECT(ePyObject) tuple); + PyObject *get(); }; inline PyObject *PyFrom(int v) @@ -58,7 +38,7 @@ public: { PyObject *pArgs = PyTuple_New(0); callPython(pArgs); - Py_DECREF(pArgs); + Org_Py_DECREF(pArgs); return Signal0<R>::operator()(); } }; @@ -72,7 +52,7 @@ public: PyObject *pArgs = PyTuple_New(1); PyTuple_SET_ITEM(pArgs, 0, PyFrom(a0)); callPython(pArgs); - Py_DECREF(pArgs); + Org_Py_DECREF(pArgs); return Signal1<R,V0>::operator()(a0); } }; @@ -87,7 +67,7 @@ public: PyTuple_SET_ITEM(pArgs, 0, PyFrom(a0)); PyTuple_SET_ITEM(pArgs, 1, PyFrom(a1)); callPython(pArgs); - Py_DECREF(pArgs); + Org_Py_DECREF(pArgs); return Signal2<R,V0,V1>::operator()(a0, a1); } }; diff --git a/lib/python/python.cpp b/lib/python/python.cpp index 119bff1c..8947bb3c 100644 --- a/lib/python/python.cpp +++ b/lib/python/python.cpp @@ -1,62 +1,130 @@ -#include <lib/python/python.h> #include <lib/base/eerror.h> /* avoid warnigs :) */ #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L -#include <Python.h> - extern "C" void init_enigma(); extern void bsodFatal(); -DEFINE_REF(TestObj); +#define SKIP_PART2 +#include <lib/python/python.h> +#undef SKIP_PART2 -TestObj::TestObj() +#ifdef PYTHON_REFCOUNT_DEBUG +ePyObject &ePyObject::operator=(PyObject *ob) { - eDebug("create %p", this); + m_ob=ob; + m_file=0; + m_line=0; + m_from=m_to=0; + m_erased=false; + return *this; } -TestObj::~TestObj() +ePyObject &ePyObject::operator=(const ePyObject &ob) { - eDebug("destroy %p", this); + m_ob=ob.m_ob; + m_file=ob.m_file; + m_line=ob.m_line; + m_from=ob.m_from; + m_to=ob.m_to; + m_erased=ob.m_erased; + return *this; } -#if 0 -ePyObject::ePyObject(void *ptr): m_object(ptr) +ePyObject::operator PyObject*() { - Py_XINCREF((PyObject*)ptr); + if (m_ob) + { + if (!m_erased && m_ob->ob_refcnt > 0) + return m_ob; + eDebug("invalid access PyObject %s with refcount <= 0 %d", + m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + return 0; } -ePyObject::ePyObject(ePyObject &p) +void ePyObject::incref(const char *file, int line) { - m_object = p.m_object; - Py_XINCREF((PyObject*)m_object); + if (!m_ob) + { + eDebug("invalid incref python object with null pointer %s %d!!!", file, line); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + if (m_erased || m_ob->ob_refcnt <= 0) + { + eDebug("invalid incref %s python object with refcounting value %d in file %s line %d!!!", + m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + if (m_ob->ob_refcnt == 0x7FFFFFFF) + { + eDebug("invalid incref %s python object with refcounting value %d (MAX_INT!!!) in file %s line %d!!!", + m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + m_file = file; + m_line = line; + m_from = m_ob->ob_refcnt; + m_to = m_from+1; + Py_INCREF(m_ob); } -ePyObject::ePyObject(): m_object(0) +void ePyObject::decref(const char *file, int line) { + if (!m_ob) + { + eDebug("invalid decref python object with null pointer %s %d!!!", file, line); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + if (m_erased || m_ob->ob_refcnt <= 0) + { + eDebug("invalid decref %s python object with refcounting value %d in file %s line %d!!!", + m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line); + if (m_file) + eDebug("last modified in file %s line %d from %d to %d", + m_file, m_line, m_from, m_to); + bsodFatal(); + } + m_file = file; + m_line = line; + m_from = m_ob->ob_refcnt; + m_to = m_from-1; + m_erased = !m_to; + Py_DECREF(m_ob); } +#endif // PYTHON_REFCOUNT_DEBUG -ePyObject::~ePyObject() -{ - Py_XDECREF((PyObject*)m_object); -} +#define SKIP_PART1 +#include <lib/python/python.h> +#undef SKIP_PART1 + +DEFINE_REF(TestObj); -ePyObject &ePyObject::operator=(ePyObject &p) +TestObj::TestObj() { - Py_XDECREF((PyObject*)m_object); - m_object = p.m_object; - Py_XINCREF((PyObject*)m_object); - return *this; + eDebug("create %p", this); } -ePyObject &ePyObject::operator=(void *object) +TestObj::~TestObj() { - Py_XDECREF((PyObject*)m_object); - m_object = object; - Py_XINCREF((PyObject*)m_object); - return *this; + eDebug("destroy %p", this); } -#endif ePython::ePython() { @@ -76,13 +144,13 @@ ePython::~ePython() int ePython::execute(const std::string &pythonfile, const std::string &funcname) { - PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue; + ePyObject pName, pModule, pDict, pFunc, pArgs, pValue; pName = PyString_FromString(pythonfile.c_str()); pModule = PyImport_Import(pName); Py_DECREF(pName); - if (pModule != NULL) + if (pModule) { pDict = PyModule_GetDict(pModule); @@ -94,7 +162,7 @@ int ePython::execute(const std::string &pythonfile, const std::string &funcname) // implement arguments.. pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); - if (pValue != NULL) + if (pValue) { printf("Result of call: %ld\n", PyInt_AsLong(pValue)); Py_DECREF(pValue); @@ -114,14 +182,14 @@ int ePython::execute(const std::string &pythonfile, const std::string &funcname) return 0; } -int ePython::call(PyObject *pFunc, PyObject *pArgs) +int ePython::call(ePyObject pFunc, ePyObject pArgs) { int res = -1; - PyObject *pValue; + ePyObject pValue; if (pFunc && PyCallable_Check(pFunc)) { pValue = PyObject_CallObject(pFunc, pArgs); - if (pValue != NULL) + if (pValue) { if (PyInt_Check(pValue)) res = PyInt_AsLong(pValue); @@ -137,26 +205,22 @@ int ePython::call(PyObject *pFunc, PyObject *pArgs) return res; } -PyObject *ePython::resolve(const std::string &pythonfile, const std::string &funcname) +ePyObject ePython::resolve(const std::string &pythonfile, const std::string &funcname) { - PyObject *pName, *pModule, *pDict, *pFunc; + ePyObject pName, pModule, pDict, pFunc; pName = PyString_FromString(pythonfile.c_str()); pModule = PyImport_Import(pName); Py_DECREF(pName); - if (pModule != NULL) + if (pModule) { pDict = PyModule_GetDict(pModule); pFunc = PyDict_GetItemString(pDict, funcname.c_str()); Py_XINCREF(pFunc); Py_DECREF(pModule); - return pFunc; - } else - { - if (PyErr_Occurred()) - PyErr_Print(); - return 0; - } + } else if (PyErr_Occurred()) + PyErr_Print(); + return pFunc; } diff --git a/lib/python/python.h b/lib/python/python.h index 46e1a03d..bcea49c5 100644 --- a/lib/python/python.h +++ b/lib/python/python.h @@ -1,14 +1,144 @@ -#ifndef __lib_python_python_h -#define __lib_python_python_h +#ifndef __lib_python_python_class_h + +#ifndef SKIP_PART2 + #define __lib_python_python_class_h +#endif #include <string> #include <lib/base/object.h> +#include <Python.h> -typedef struct _object PyObject; +#define PYTHON_REFCOUNT_DEBUG -// useable for debugging python refcounting +#if !defined(SKIP_PART1) && !defined(SWIG) +class ePyObject +{ + PyObject *m_ob; +#ifdef PYTHON_REFCOUNT_DEBUG + const char *m_file; + int m_line, m_from, m_to; + bool m_erased; +#endif +public: + inline ePyObject(); + inline ePyObject(const ePyObject &ob); + inline ePyObject(PyObject *ob); + inline ePyObject(PyDictObject *ob); + inline ePyObject(PyTupleObject *ob); + inline ePyObject(PyListObject *ob); + inline ePyObject(PyStringObject *ob); + operator bool() { return !!m_ob; } + ePyObject &operator=(const ePyObject &); + ePyObject &operator=(PyObject *); + ePyObject &operator=(PyDictObject *ob) { return operator=((PyObject*)ob); } + ePyObject &operator=(PyTupleObject *ob) { return operator=((PyObject*)ob); } + ePyObject &operator=(PyListObject *ob) { return operator=((PyObject*)ob); } + ePyObject &operator=(PyStringObject *ob) { return operator=((PyObject*)ob); } + operator PyObject*(); + operator PyTupleObject*() { return (PyTupleObject*)operator PyObject*(); } + operator PyListObject*() { return (PyListObject*)operator PyObject*(); } + operator PyStringObject*() { return (PyStringObject*)operator PyObject*(); } + operator PyDictObject*() { return (PyDictObject*)operator PyObject*(); } + PyObject *operator->() { return operator PyObject*(); } +#ifdef PYTHON_REFCOUNT_DEBUG + void incref(const char *file, int line); + void decref(const char *file, int line); +#else + void incref(); + void decref(); +#endif +}; -extern PyObject *New_TestObj(); +inline ePyObject::ePyObject() + :m_ob(0) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +inline ePyObject::ePyObject(const ePyObject &ob) + :m_ob(ob.m_ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(ob.m_file), m_line(ob.m_line) + ,m_from(ob.m_from), m_to(ob.m_to), m_erased(ob.m_erased) +#endif +{ +} + +inline ePyObject::ePyObject(PyObject *ob) + :m_ob(ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +inline ePyObject::ePyObject(PyDictObject *ob) + :m_ob((PyObject*)ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +inline ePyObject::ePyObject(PyTupleObject *ob) + :m_ob((PyObject*)ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +inline ePyObject::ePyObject(PyListObject *ob) + :m_ob((PyObject*)ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +inline ePyObject::ePyObject(PyStringObject *ob) + :m_ob((PyObject*)ob) +#ifdef PYTHON_REFCOUNT_DEBUG + ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false) +#endif +{ +} + +#ifndef PYTHON_REFCOUNT_DEBUG +inline ePyObject &ePyObject::operator=(PyObject *ob) +{ + m_ob=ob; + return *this; +} + +inline ePyObject &ePyObject::operator=(const ePyObject &ob) +{ + m_ob=ob.m_ob; + return *this; +} + +inline ePyObject::operator PyObject*() +{ + return m_ob; +} + +inline void ePyObject::incref() +{ + Py_INCREF(m_ob); +} + +inline void ePyObject::decref() +{ + Py_DECREF(m_ob); +} + +#endif // ! PYTHON_REFCOUNT_DEBUG + +#endif // !SWIG && !SKIP_PART1 + +#ifndef SKIP_PART2 class TestObj { @@ -19,19 +149,76 @@ public: }; TEMPLATE_TYPEDEF(ePtr<TestObj>, TestObjPtr); +extern PyObject *New_TestObj(); + #ifndef SWIG -/* class ePyObject + +#ifdef PYTHON_REFCOUNT_DEBUG +inline void Impl_Py_DECREF(const char* file, int line, const ePyObject &obj) { - void *m_object; -public: - ePyObject(void *ptr); - ePyObject(ePyObject &p); - ePyObject(); - ePyObject &operator=(ePyObject &p); - ePyObject &operator=(void *p); - ~ePyObject(); - void *get() { return m_object; } -}; */ + ((ePyObject*)(&obj))->decref(file, line); +} + +inline void Impl_Py_INCREF(const char* file, int line, const ePyObject &obj) +{ + ((ePyObject*)(&obj))->incref(file, line); +} + +inline void Impl_Py_XDECREF(const char* file, int line, const ePyObject &obj) +{ + if (obj) + ((ePyObject*)(&obj))->decref(file, line); +} + +inline void Impl_Py_XINCREF(const char* file, int line, const ePyObject &obj) +{ + if (obj) + ((ePyObject*)(&obj))->incref(file, line); +} +#else +inline void Impl_Py_DECREF(const ePyObject &obj) +{ + ((ePyObject*)(&obj))->decref(); +} + +inline void Impl_Py_INCREF(const ePyObject &obj) +{ + ((ePyObject*)(&obj))->incref(); +} + +inline void Impl_Py_XDECREF(const ePyObject &obj) +{ + if (obj) + ((ePyObject*)(&obj))->decref(); +} + +inline void Impl_Py_XINCREF(const ePyObject &obj) +{ + if (obj) + ((ePyObject*)(&obj))->incref(); +} +#endif + +inline void Impl_DECREF(PyObject *ob) +{ + Py_DECREF(ob); +} +#define Org_Py_DECREF(obj) Impl_DECREF(obj) +#undef Py_DECREF +#undef Py_XDECREF +#undef Py_INCREF +#undef Py_XINCREF +#ifdef PYTHON_REFCOUNT_DEBUG +#define Py_DECREF(obj) Impl_Py_DECREF(__FILE__, __LINE__, obj) +#define Py_XDECREF(obj) Impl_Py_XDECREF(__FILE__, __LINE__, obj) +#define Py_INCREF(obj) Impl_Py_INCREF(__FILE__, __LINE__, obj) +#define Py_XINCREF(obj) Impl_Py_XINCREF(__FILE__, __LINE__, obj) +#else +#define Py_DECREF(obj) Impl_Py_DECREF(obj) +#define Py_XDECREF(obj) Impl_Py_XDECREF(obj) +#define Py_INCREF(obj) Impl_Py_INCREF(obj) +#define Py_XINCREF(obj) Impl_Py_XINCREF(obj) +#endif class ePython { @@ -39,10 +226,12 @@ public: ePython(); ~ePython(); int execute(const std::string &pythonfile, const std::string &funcname); - static int call(PyObject *pFunc, PyObject *args); - static PyObject *resolve(const std::string &pythonfile, const std::string &funcname); + static int call(ePyObject pFunc, ePyObject args); + static ePyObject resolve(const std::string &pythonfile, const std::string &funcname); private: }; + #endif // SWIG +#endif // SKIP_PART2 -#endif +#endif // __lib_python_python_class_h diff --git a/lib/python/swig.h b/lib/python/swig.h index c9be9695..c094b646 100644 --- a/lib/python/swig.h +++ b/lib/python/swig.h @@ -18,11 +18,13 @@ typedef x y; \ #define SWIG_OUTPUT OUTPUT #define SWIG_NAMED_OUTPUT(x) OUTPUT #define SWIG_VOID(x) void +#define SWIG_PYOBJECT(x) PyObject* #else #define SWIG_INPUT #define SWIG_OUTPUT #define SWIG_NAMED_OUTPUT(x) x #define SWIG_VOID(x) x +#define SWIG_PYOBJECT(x) x #endif #endif |
