aboutsummaryrefslogtreecommitdiff
path: root/lib/python
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python')
-rw-r--r--lib/python/connections.cpp26
-rw-r--r--lib/python/connections.h38
-rw-r--r--lib/python/python.cpp156
-rw-r--r--lib/python/python.h227
-rw-r--r--lib/python/swig.h2
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