22
33#include <stdbool.h>
44#include <stdint.h>
5+ #include <stdlib.h>
6+ #include <string.h>
57
68#include "uast.h"
79
10+ // Used to store references to the Pyobjects instanced in String() and
11+ // ItemAt() methods. Those can't be DECREF'ed to 0 because libuast uses the
12+ // so we pass ownership to these lists and free them at the end of filter()
13+ static PyObject * stringAllocsList ;
14+ static PyObject * itemAtAllocsList ;
15+
816static PyObject * Attribute (const void * node , const char * prop ) {
917 PyObject * n = (PyObject * )node ;
1018 return PyObject_GetAttrString (n , prop );
@@ -20,28 +28,35 @@ static const char *String(const void *node, const char *prop) {
2028 PyObject * o = Attribute (node , prop );
2129 if (o != NULL ) {
2230 retval = PyUnicode_AsUTF8 (o );
31+ PyList_Append (stringAllocsList , o );
2332 Py_DECREF (o );
2433 }
2534 return retval ;
2635}
2736
2837static size_t Size (const void * node , const char * prop ) {
38+ size_t retval = 0 ;
2939 PyObject * o = Attribute (node , prop );
30- return o ? PySequence_Size (o ) : 0 ;
40+ if (o != NULL ) {
41+ retval = PySequence_Size (o );
42+ Py_DECREF (o );
43+ }
44+
45+ return retval ;
3146}
3247
3348static PyObject * ItemAt (PyObject * object , int index ) {
3449 PyObject * retval = NULL ;
3550 PyObject * seq = PySequence_Fast (object , "expected a sequence" );
3651 if (seq != NULL ) {
3752 retval = PyList_GET_ITEM (seq , index );
53+ PyList_Append (itemAtAllocsList , seq );
3854 Py_DECREF (seq );
3955 }
4056
4157 return retval ;
4258}
4359
44-
4560static const char * InternalType (const void * node ) {
4661 return String (node , "internal_type" );
4762}
@@ -277,14 +292,20 @@ static PyObject *PyFilter(PyObject *self, PyObject *args)
277292 PyObject * obj = NULL ;
278293 const char * query = NULL ;
279294
280- if (!PyArg_ParseTuple (args , "Os" , & obj , & query ))
295+ if (!PyArg_ParseTuple (args , "Os" , & obj , & query )) {
281296 return NULL ;
297+ }
298+
299+ itemAtAllocsList = PyList_New (0 );
300+ stringAllocsList = PyList_New (0 );
282301
283302 Nodes * nodes = UastFilter (ctx , obj , query );
284303 if (!nodes ) {
285304 char * error = LastError ();
286305 PyErr_SetString (PyExc_RuntimeError , error );
287306 free (error );
307+ Py_DECREF (stringAllocsList );
308+ Py_DECREF (itemAtAllocsList );
288309 return NULL ;
289310 }
290311 size_t len = NodesSize (nodes );
@@ -298,6 +319,9 @@ static PyObject *PyFilter(PyObject *self, PyObject *args)
298319 NodesFree (nodes );
299320 PyObject * iter = PySeqIter_New (list );
300321 Py_DECREF (list );
322+
323+ Py_DECREF (itemAtAllocsList );
324+ Py_DECREF (stringAllocsList );
301325 return iter ;
302326}
303327
0 commit comments