Skip to content

Commit 9cb329a

Browse files
committed
[mypyc] Fix function wrapper memory leak
1 parent 2433566 commit 9cb329a

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

mypyc/lib-rt/function_wrapper.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ static PyObject* CPyFunction_Vectorcall(PyObject *func, PyObject *const *args, s
196196
}
197197

198198

199+
// Steals ml, name, and code. Borrows module.
199200
static CPyFunction* CPyFunction_Init(CPyFunction *op, PyMethodDef *ml, PyObject* name,
200201
PyObject *module, PyObject* code, bool set_self) {
201202
PyCFunctionObject *cf = (PyCFunctionObject *)op;
@@ -206,12 +207,10 @@ static CPyFunction* CPyFunction_Init(CPyFunction *op, PyMethodDef *ml, PyObject*
206207
Py_XINCREF(module);
207208
cf->m_module = module;
208209

209-
Py_INCREF(name);
210210
op->func_name = name;
211211

212212
((PyCMethodObject *)op)->mm_class = NULL;
213213

214-
Py_XINCREF(code);
215214
op->func_code = code;
216215

217216
CPyFunction_func_vectorcall(op) = CPyFunction_Vectorcall;
@@ -243,7 +242,7 @@ PyObject* CPyFunction_New(PyObject *module, const char *filename, const char *fu
243242
PyCFunction func, int func_flags, const char *func_doc,
244243
int first_line, int code_flags, bool has_self_arg) {
245244
PyMethodDef *method = NULL;
246-
PyObject *code = NULL, *op = NULL;
245+
PyObject *code = NULL, *name = NULL, *op = NULL;
247246
bool set_self = false;
248247

249248
#ifdef Py_GIL_DISABLED
@@ -280,18 +279,24 @@ PyObject* CPyFunction_New(PyObject *module, const char *filename, const char *fu
280279
if (unlikely(!code)) {
281280
goto err;
282281
}
282+
name = PyUnicode_FromString(funcname);
283+
if (unlikely(!name)) {
284+
goto err;
285+
}
283286

284287
// Set m_self inside the function wrapper only if the wrapped function has no self arg
285288
// to pass m_self as the self arg when the function is called.
286289
// When the function has a self arg, it will come in the args vector passed to the
287290
// vectorcall handler.
288291
set_self = !has_self_arg;
289-
op = (PyObject *)CPyFunction_Init(PyObject_GC_New(CPyFunction, CPyFunctionType),
290-
method, PyUnicode_FromString(funcname), module,
291-
code, set_self);
292-
if (unlikely(!op)) {
292+
CPyFunction *raw = PyObject_GC_New(CPyFunction, CPyFunctionType);
293+
if (unlikely(!raw)) {
293294
goto err;
294295
}
296+
op = (PyObject *)CPyFunction_Init(raw, method, name, module, code, set_self);
297+
method = NULL;
298+
name = NULL;
299+
code = NULL;
295300
PyObject_GC_Track(op);
296301
return op;
297302

@@ -300,5 +305,7 @@ PyObject* CPyFunction_New(PyObject *module, const char *filename, const char *fu
300305
if (method) {
301306
PyMem_Free(method);
302307
}
308+
Py_XDECREF(name);
309+
Py_XDECREF(code);
303310
return NULL;
304311
}

0 commit comments

Comments
 (0)