From 1a23e8233e6c1cbc30b9ddee4df153c21f4b282b Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 31 Aug 2004 04:07:35 +0000 Subject: "" svn path=/trunk/; revision=1982 --- externals/grill/py/readme.txt | 4 + externals/grill/py/source/bound.cpp | 2 + externals/grill/py/source/clmeth.cpp | 141 ++++++++++++++++++--------------- externals/grill/py/source/main.cpp | 60 +++++++------- externals/grill/py/source/modmeth.cpp | 66 +++++++-------- externals/grill/py/source/pyargs.cpp | 12 +-- externals/grill/py/source/pyext.cpp | 15 ++-- externals/grill/py/source/register.cpp | 4 +- 8 files changed, 169 insertions(+), 135 deletions(-) (limited to 'externals/grill/py') diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt index aa9a96a6..57a44661 100644 --- a/externals/grill/py/readme.txt +++ b/externals/grill/py/readme.txt @@ -82,6 +82,10 @@ o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" Version history: +0.1.4: +- ADD: better (and independent) handling of inlet and outlet count (as class variables or dynamically initialized in __init__) +- FIX: many memory leaks associated to ***GetItem stuff (big thanks to sven!) + 0.1.3: - FIX: class variables are now set atomic if parameter list has only 1 element - ADD: introduced shortcut "pyx" for pyext. diff --git a/externals/grill/py/source/bound.cpp b/externals/grill/py/source/bound.cpp index 9578e4c0..75a462e4 100644 --- a/externals/grill/py/source/bound.cpp +++ b/externals/grill/py/source/bound.cpp @@ -38,6 +38,8 @@ bool pyext::boundmeth(flext_base *,t_symbol *sym,int argc,t_atom *argv,void *dat Py_XDECREF(ret); } + Py_XDECREF(args); + PY_UNLOCK return true; } diff --git a/externals/grill/py/source/clmeth.cpp b/externals/grill/py/source/clmeth.cpp index d3b909ff..a9770834 100644 --- a/externals/grill/py/source/clmeth.cpp +++ b/externals/grill/py/source/clmeth.cpp @@ -122,9 +122,11 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args) if(!ret) { #if PY_VERSION_HEX >= 0x02020000 + // \todo borrowed or new??? ret = PyObject_GenericGetAttr(self,name); #else if(PyInstance_Check(self)) + // borrowed reference ret = PyDict_GetItem(((PyInstanceObject *)self)->in_dict,name); #endif } @@ -135,48 +137,54 @@ PyObject* pyext::pyext_getattr(PyObject *,PyObject *args) PyObject *pyext::pyext_outlet(PyObject *,PyObject *args) { BL ok = false; - if(PySequence_Check(args)) { - PyObject *self = PySequence_GetItem(args,0); - PyObject *outl = PySequence_GetItem(args,1); - if( - self && PyInstance_Check(self) && - outl && PyInt_Check(outl) - ) { - pyext *ext = GetThis(self); - - I sz = PySequence_Size(args); - PyObject *val; - BL tp = sz == 3 && PySequence_Check(PySequence_GetItem(args,2)); - - if(tp) - val = PySequence_GetItem(args,2); // borrowed - else - val = PySequence_GetSlice(args,2,sz); // new ref - - AtomList *lst = GetPyArgs(val); - if(lst) { - I o = PyInt_AsLong(outl); - if(o >= 1 && o <= ext->Outlets()) { - // by using the queue there is no immediate call of the next object - // deadlock would occur if this was another py/pyext object! - if(lst->Count() && IsSymbol((*lst)[0])) - ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1); + + // should always be a tuple! + FLEXT_ASSERT(PyTuple_Check(args)); + + // borrowed references! + PyObject *self = PyTuple_GetItem(args,0); + PyObject *outl = PyTuple_GetItem(args,1); + if( + self && PyInstance_Check(self) && + outl && PyInt_Check(outl) + ) { + pyext *ext = GetThis(self); + + I sz = PyTuple_Size(args); + PyObject *val; + + BL tp = + sz == 3 && + PySequence_Check( + val = PyTuple_GetItem(args,2) // borrow reference + ); + + if(!tp) + val = PySequence_GetSlice(args,2,sz); // new ref + + AtomList *lst = GetPyArgs(val); + if(lst) { + I o = PyInt_AsLong(outl); + if(o >= 1 && o <= ext->Outlets()) { + // by using the queue there is no immediate call of the next object + // deadlock would occur if this was another py/pyext object! + if(lst->Count() && IsSymbol((*lst)[0])) + ext->ToQueueAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1); // ext->ToOutAnything(o-1,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1); - else - ext->ToQueueList(o-1,*lst); -// ext->ToOutList(o-1,*lst); - } else - post("pyext: outlet index out of range"); - - ok = true; + ext->ToQueueList(o-1,*lst); +// ext->ToOutList(o-1,*lst); } - else - post("py/pyext - No data to send"); - if(lst) delete lst; + else + post("pyext: outlet index out of range"); - if(!tp) Py_DECREF(val); + ok = true; } + else + post("py/pyext - No data to send"); + if(lst) delete lst; + + if(!tp) Py_DECREF(val); } if(!ok) post("pyext - Syntax: _outlet(self,outlet,args...)"); @@ -245,40 +253,43 @@ PyObject *pyext::pyext_isthreaded(PyObject *,PyObject *) //! Send message to canvas PyObject *pyext::pyext_tocanvas(PyObject *,PyObject *args) { + FLEXT_ASSERT(PyTuple_Check(args)); + BL ok = false; - if(PySequence_Check(args)) { - PyObject *self = PySequence_GetItem(args,0); - if(self && PyInstance_Check(self)) { - pyext *ext = GetThis(self); + PyObject *self = PyTuple_GetItem(args,0); // borrowed ref + if(self && PyInstance_Check(self)) { + pyext *ext = GetThis(self); - I sz = PySequence_Size(args); - PyObject *val; - BL tp = sz == 2 && PySequence_Check(PyTuple_GetItem(args,1)); + I sz = PySequence_Size(args); + PyObject *val; - if(tp) - val = PySequence_GetItem(args,1); // borrowed - else - val = PySequence_GetSlice(args,1,sz); // new ref - - AtomList *lst = GetPyArgs(val); - if(lst) { - t_glist *gl = ext->thisCanvas(); //canvas_getcurrent(); - t_class **cl = (t_pd *)gl; - if(cl) { - pd_forwardmess(cl,lst->Count(),lst->Atoms()); - } + BL tp = + sz == 2 && + PySequence_Check( + val = PyTuple_GetItem(args,1) // borrowed ref + ); + + if(!tp) + val = PyTuple_GetSlice(args,1,sz); // new ref + + AtomList *lst = GetPyArgs(val); + if(lst) { + t_glist *gl = ext->thisCanvas(); //canvas_getcurrent(); + t_class **cl = (t_pd *)gl; + if(cl) { + pd_forwardmess(cl,lst->Count(),lst->Atoms()); + } #ifdef FLEXT_DEBUG - else - post("pyext - no parent canvas?!"); + else + post("pyext - no parent canvas?!"); #endif - ok = true; - } - else - post("py/pyext - No data to send"); - if(lst) delete lst; - - if(!tp) Py_DECREF(val); + ok = true; } + else + post("py/pyext - No data to send"); + if(lst) delete lst; + + if(!tp) Py_DECREF(val); } if(!ok) post("pyext - Syntax: _tocanvas(self,args...)"); diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp index 034fefd2..20e7a865 100644 --- a/externals/grill/py/source/main.cpp +++ b/externals/grill/py/source/main.cpp @@ -279,7 +279,7 @@ V py::AddToPath(const C *dir) if(pobj && PyList_Check(pobj)) { int i,n = PyList_Size(pobj); for(i = 0; i < n; ++i) { - PyObject *pt = PyList_GetItem(pobj,i); + PyObject *pt = PyList_GetItem(pobj,i); // borrowed reference if(PyString_Check(pt) && !strcmp(dir,PyString_AS_STRING(pt))) break; } if(i == n) { // string is not yet existent in path @@ -296,33 +296,37 @@ static PyObject *output = NULL; // post to the console PyObject* py::StdOut_Write(PyObject* self, PyObject* args) { - if(PySequence_Check(args)) { - int sz = PySequence_Size(args); - for(int i = 0; i < sz; ++i) { - PyObject *val = PySequence_GetItem(args,i); // borrowed - PyObject *str = PyObject_Str(val); - char *cstr = PyString_AS_STRING(str); - char *lf = strchr(cstr,'\n'); - - // line feed in string - if(!lf) { - // no -> just append - if(output) - PyString_ConcatAndDel(&output,str); - else - output = str; - } - else { - // yes -> append up to line feed, reset output buffer to string remainder - PyObject *part = PyString_FromStringAndSize(cstr,lf-cstr); - if(output) - PyString_ConcatAndDel(&output,part); - else - output = part; - post(PyString_AS_STRING(output)); - Py_DECREF(output); - output = PyString_FromString(lf+1); - } + // should always be a tuple + FLEXT_ASSERT(PyTuple_Check(args)); + + int sz = PyTuple_Size(args); + for(int i = 0; i < sz; ++i) { + PyObject *val = PyTuple_GetItem(args,i); // borrowed reference + PyObject *str = PyObject_Str(val); // new reference + char *cstr = PyString_AS_STRING(str); + char *lf = strchr(cstr,'\n'); + + // line feed in string + if(!lf) { + // no -> just append + if(output) + PyString_ConcatAndDel(&output,str); // str is decrefd + else + output = str; // take str reference + } + else { + // yes -> append up to line feed, reset output buffer to string remainder + PyObject *part = PyString_FromStringAndSize(cstr,lf-cstr); // new reference + if(output) + PyString_ConcatAndDel(&output,part); // str is decrefd + else + output = part; // take str reference + + // output concatenated string + post(PyString_AS_STRING(output)); + + Py_DECREF(output); + output = PyString_FromString(lf+1); // new reference } } diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp index b3a98c98..0fe0cc6a 100644 --- a/externals/grill/py/source/modmeth.cpp +++ b/externals/grill/py/source/modmeth.cpp @@ -104,7 +104,7 @@ PyObject *py::py_inchannels(PyObject *self,PyObject *args) #if FLEXT_SYS == FLEXT_SYS_PD I ch = sys_get_inchannels(); #elif FLEXT_SYS == FLEXT_SYS_MAX - I ch = sys_getch(); // not functioning + I ch = sys_getch(); // not working #else #pragma message("Not implemented!") ch = 0; @@ -117,7 +117,7 @@ PyObject *py::py_outchannels(PyObject *self,PyObject *args) #if FLEXT_SYS == FLEXT_SYS_PD I ch = sys_get_outchannels(); #elif FLEXT_SYS == FLEXT_SYS_MAX - I ch = sys_getch(); // not functioning + I ch = sys_getch(); // not working #else #pragma message("Not implemented!") ch = 0; @@ -127,41 +127,45 @@ PyObject *py::py_outchannels(PyObject *self,PyObject *args) PyObject *py::py_send(PyObject *,PyObject *args) { - if(PySequence_Check(args)) { - PyObject *name = PySequence_GetItem(args,0); // borrowed - if(name && PyString_Check(name)) { - const t_symbol *recv = MakeSymbol(PyString_AsString(name)); - I sz = PySequence_Size(args); - PyObject *val; - BL tp = sz == 2 && PySequence_Check(PySequence_GetItem(args,1)); - - if(tp) - val = PySequence_GetItem(args,1); // borrowed + // should always be a tuple + FLEXT_ASSERT(PyTuple_Check(args)); + + PyObject *name = PyTuple_GetItem(args,0); // borrowed reference + if(name && PyString_Check(name)) { + const t_symbol *recv = MakeSymbol(PyString_AsString(name)); + int sz = PySequence_Size(args); + PyObject *val; + + bool tp = + sz == 2 && + PySequence_Check( + val = PyTuple_GetItem(args,1) // borrowed ref + ); + + if(!tp) + val = PySequence_GetSlice(args,1,sz); // new ref + + AtomList *lst = GetPyArgs(val); + if(lst) { + bool ok; + if(lst->Count() && IsSymbol((*lst)[0])) + ok = Forward(recv,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1); else - val = PySequence_GetSlice(args,1,sz); // new ref - - AtomList *lst = GetPyArgs(val); - if(lst) { - bool ok; - if(lst->Count() && IsSymbol((*lst)[0])) - ok = Forward(recv,GetSymbol((*lst)[0]),lst->Count()-1,lst->Atoms()+1); - else - ok = Forward(recv,*lst); + ok = Forward(recv,*lst); #ifdef FLEXT_DEBUG - if(!ok) - post("py/pyext - Receiver doesn't exist"); + if(!ok) + post("py/pyext - Receiver doesn't exist"); #endif - } - else - post("py/pyext - No data to send"); - if(lst) delete lst; - - if(!tp) Py_DECREF(val); } - else - post("py/pyext - Send name is invalid"); + else + post("py/pyext - No data to send"); + if(lst) delete lst; + + if(!tp) Py_DECREF(val); } + else + post("py/pyext - Send name is invalid"); Py_INCREF(Py_None); return Py_None; diff --git a/externals/grill/py/source/pyargs.cpp b/externals/grill/py/source/pyargs.cpp index 1b204273..69e403b0 100644 --- a/externals/grill/py/source/pyargs.cpp +++ b/externals/grill/py/source/pyargs.cpp @@ -116,10 +116,10 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self) for(I ix = 0; ix < rargc; ++ix) { PyObject *arg; - switch(tp) { - case sequ: arg = PySequence_GetItem(pValue,ix); break; - default: arg = pValue; - } + if(tp == sequ) + arg = PySequence_GetItem(pValue,ix); // new reference + else + arg = pValue; if(PyInt_Check(arg)) SetInt((*ret)[ix],PyInt_AsLong(arg)); else if(PyLong_Check(arg)) SetInt((*ret)[ix],PyLong_AsLong(arg)); @@ -127,6 +127,7 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self) else if(PyString_Check(arg)) SetString((*ret)[ix],PyString_AsString(arg)); else if(ix == 0 && self && PyInstance_Check(arg)) { // assumed to be self ... that should be checked _somehow_ !!! + Py_INCREF(arg); *self = arg; } else { @@ -139,7 +140,8 @@ flext::AtomList *py::GetPyArgs(PyObject *pValue,PyObject **self) Py_XDECREF(tp); ok = false; } - // No DECREF for arg -> borrowed from pValue! + + if(tp == sequ) Py_DECREF(arg); } if(!ok) { diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp index 7ce0995c..adaacc0e 100644 --- a/externals/grill/py/source/pyext.cpp +++ b/externals/grill/py/source/pyext.cpp @@ -76,10 +76,15 @@ V pyext::Setup(t_classid c) pyext *pyext::GetThis(PyObject *self) { PyObject *th = PyObject_GetAttrString(self,"_this"); - pyext *ret = th?(pyext *)PyLong_AsVoidPtr(th):NULL; - PyErr_Clear(); - Py_XDECREF(th); - return ret; + if(th) { + pyext *ret = static_cast(PyLong_AsVoidPtr(th)); + Py_DECREF(th); + return ret; + } + else { + PyErr_Clear(); + return NULL; + } } @@ -385,7 +390,7 @@ void pyext::m_set(int argc,const t_atom *argv) if(PySequence_Size(pval) == 1) { // reduce lists of one element to element itself - PyObject *val1 = PySequence_GetItem(pval,0); + PyObject *val1 = PySequence_GetItem(pval,0); // new reference Py_DECREF(pval); pval = val1; } diff --git a/externals/grill/py/source/register.cpp b/externals/grill/py/source/register.cpp index 9fe4dfc7..16e1df65 100644 --- a/externals/grill/py/source/register.cpp +++ b/externals/grill/py/source/register.cpp @@ -66,7 +66,7 @@ V py::Reregister(const C *regnm) else { I cnt = PySequence_Size(reg); for(I i = 0; i < cnt; ++i) { - PyObject *it = PySequence_GetItem(reg,i); // borrowed!! + PyObject *it = PySequence_GetItem(reg,i); // new reference if(!it || !PyInt_Check(it)) { post("%s - Corrupt registry?!",thisName()); } @@ -76,6 +76,8 @@ V py::Reregister(const C *regnm) th->dict = dict; th->Reload(); } + + Py_XDECREF(it); } } } -- cgit v1.2.1