Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit 0fd9105

Browse files
author
Juanjo Alvarez
committed
Store and defer allocations of problematic pyobjects to the end of filter()
Signed-off-by: Juanjo Alvarez <juanjo@sourced.tech>
1 parent b07ac39 commit 0fd9105

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

bblfsh/pyuast.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
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+
816
static 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

2837
static 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

3348
static 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-
4560
static 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

Comments
 (0)