Commit b3c2e0d6 authored by Stefan Behnel's avatar Stefan Behnel

Prevent calling PyObject_GC_Track() in __Pyx_CyFunction_New() when...

Prevent calling PyObject_GC_Track() in __Pyx_CyFunction_New() when instantiating a fused function before the object fields of the fused function subtype are fully initialised.
See https://bugs.python.org/issue38392
Closes GH-3215.
Supersedes GH-3216.
parent acd3fdcb
...@@ -17,6 +17,10 @@ Features added ...@@ -17,6 +17,10 @@ Features added
Bugs fixed Bugs fixed
---------- ----------
* Creating a fused function attached it to the garbage collector before it
was fully initialised, thus risking crashes in rare failure cases.
Original patch by achernomorov. (Github issue #3215)
* The compilation cache in ``cython.inline("…")`` failed to take the language * The compilation cache in ``cython.inline("…")`` failed to take the language
level into account. level into account.
Patch by will-ca. (Github issue #3419) Patch by will-ca. (Github issue #3419)
......
...@@ -9387,11 +9387,11 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin): ...@@ -9387,11 +9387,11 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
if self.specialized_cpdefs or self.is_specialization: if self.specialized_cpdefs or self.is_specialization:
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("FusedFunction", "CythonFunction.c")) UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
constructor = "__pyx_FusedFunction_NewEx" constructor = "__pyx_FusedFunction_New"
else: else:
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
UtilityCode.load_cached("CythonFunction", "CythonFunction.c")) UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
constructor = "__Pyx_CyFunction_NewEx" constructor = "__Pyx_CyFunction_New"
if self.code_object: if self.code_object:
code_object_result = self.code_object.py_result() code_object_result = self.code_object.py_result()
......
//////////////////// CythonFunctionShared.proto ////////////////////
//////////////////// CythonFunction.proto ////////////////////
#define __Pyx_CyFunction_USED 1 #define __Pyx_CyFunction_USED 1
#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 #define __Pyx_CYFUNCTION_STATICMETHOD 0x01
...@@ -50,10 +50,7 @@ static PyTypeObject *__pyx_CyFunctionType = 0; ...@@ -50,10 +50,7 @@ static PyTypeObject *__pyx_CyFunctionType = 0;
#define __Pyx_CyFunction_Check(obj) (__Pyx_TypeCheck(obj, __pyx_CyFunctionType)) #define __Pyx_CyFunction_Check(obj) (__Pyx_TypeCheck(obj, __pyx_CyFunctionType))
#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml,
__Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
int flags, PyObject* qualname, int flags, PyObject* qualname,
PyObject *self, PyObject *self,
PyObject *module, PyObject *globals, PyObject *module, PyObject *globals,
...@@ -72,7 +69,8 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, ...@@ -72,7 +69,8 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
static int __pyx_CyFunction_init(void); static int __pyx_CyFunction_init(void);
//////////////////// CythonFunction ////////////////////
//////////////////// CythonFunctionShared ////////////////////
//@substitute: naming //@substitute: naming
//@requires: CommonStructures.c::FetchCommonType //@requires: CommonStructures.c::FetchCommonType
////@requires: ObjectHandling.c::PyObjectGetAttrStr ////@requires: ObjectHandling.c::PyObjectGetAttrStr
...@@ -446,11 +444,9 @@ static PyMethodDef __pyx_CyFunction_methods[] = { ...@@ -446,11 +444,9 @@ static PyMethodDef __pyx_CyFunction_methods[] = {
#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
#endif #endif
static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname,
static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { if (unlikely(op == NULL))
__pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
if (op == NULL)
return NULL; return NULL;
op->flags = flags; op->flags = flags;
__Pyx_CyFunction_weakreflist(op) = NULL; __Pyx_CyFunction_weakreflist(op) = NULL;
...@@ -478,7 +474,6 @@ static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int f ...@@ -478,7 +474,6 @@ static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int f
op->defaults_kwdict = NULL; op->defaults_kwdict = NULL;
op->defaults_getter = NULL; op->defaults_getter = NULL;
op->func_annotations = NULL; op->func_annotations = NULL;
PyObject_GC_Track(op);
return (PyObject *) op; return (PyObject *) op;
} }
...@@ -779,11 +774,36 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, Py ...@@ -779,11 +774,36 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, Py
Py_INCREF(dict); Py_INCREF(dict);
} }
//////////////////// CythonFunction.proto ////////////////////
static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml,
int flags, PyObject* qualname,
PyObject *closure,
PyObject *module, PyObject *globals,
PyObject* code);
//////////////////// CythonFunction ////////////////////
//@requires: CythonFunctionShared
static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname,
PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
PyObject *op = __Pyx_CyFunction_Init(
PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType),
ml, flags, qualname, closure, module, globals, code
);
if (likely(op)) {
PyObject_GC_Track(op);
}
return op;
}
//////////////////// CyFunctionClassCell.proto //////////////////// //////////////////// CyFunctionClassCell.proto ////////////////////
static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj);/*proto*/ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj);/*proto*/
//////////////////// CyFunctionClassCell //////////////////// //////////////////// CyFunctionClassCell ////////////////////
//@requires: CythonFunction //@requires: CythonFunctionShared
static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) { static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) {
Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions); Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions);
...@@ -806,7 +826,9 @@ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *class ...@@ -806,7 +826,9 @@ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *class
return 0; return 0;
} }
//////////////////// FusedFunction.proto //////////////////// //////////////////// FusedFunction.proto ////////////////////
typedef struct { typedef struct {
__pyx_CyFunctionObject func; __pyx_CyFunctionObject func;
PyObject *__signatures__; PyObject *__signatures__;
...@@ -814,11 +836,8 @@ typedef struct { ...@@ -814,11 +836,8 @@ typedef struct {
PyObject *self; PyObject *self;
} __pyx_FusedFunctionObject; } __pyx_FusedFunctionObject;
#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ static PyObject *__pyx_FusedFunction_New(PyMethodDef *ml, int flags,
__pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code) PyObject *qualname, PyObject *closure,
static PyObject *__pyx_FusedFunction_New(PyTypeObject *type,
PyMethodDef *ml, int flags,
PyObject *qualname, PyObject *self,
PyObject *module, PyObject *globals, PyObject *module, PyObject *globals,
PyObject *code); PyObject *code);
...@@ -829,24 +848,27 @@ static int __pyx_FusedFunction_init(void); ...@@ -829,24 +848,27 @@ static int __pyx_FusedFunction_init(void);
#define __Pyx_FusedFunction_USED #define __Pyx_FusedFunction_USED
//////////////////// FusedFunction //////////////////// //////////////////// FusedFunction ////////////////////
//@requires: CythonFunction //@requires: CythonFunctionShared
static PyObject * static PyObject *
__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, __pyx_FusedFunction_New(PyMethodDef *ml, int flags,
PyObject *qualname, PyObject *self, PyObject *qualname, PyObject *closure,
PyObject *module, PyObject *globals, PyObject *module, PyObject *globals,
PyObject *code) PyObject *code)
{ {
__pyx_FusedFunctionObject *fusedfunc = PyObject *op = __Pyx_CyFunction_Init(
(__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname, // __pyx_CyFunctionObject is correct below since that's the cast that we want.
self, module, globals, code); PyObject_GC_New(__pyx_CyFunctionObject, __pyx_FusedFunctionType),
if (!fusedfunc) ml, flags, qualname, closure, module, globals, code
return NULL; );
if (likely(op)) {
fusedfunc->__signatures__ = NULL; __pyx_FusedFunctionObject *fusedfunc = (__pyx_FusedFunctionObject *) op;
fusedfunc->type = NULL; fusedfunc->__signatures__ = NULL;
fusedfunc->self = NULL; fusedfunc->type = NULL;
return (PyObject *) fusedfunc; fusedfunc->self = NULL;
PyObject_GC_Track(op);
}
return op;
} }
static void static void
...@@ -896,7 +918,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type) ...@@ -896,7 +918,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
if (obj == Py_None) if (obj == Py_None)
obj = NULL; obj = NULL;
meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx( meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_New(
((PyCFunctionObject *) func)->m_ml, ((PyCFunctionObject *) func)->m_ml,
((__pyx_CyFunctionObject *) func)->flags, ((__pyx_CyFunctionObject *) func)->flags,
((__pyx_CyFunctionObject *) func)->func_qualname, ((__pyx_CyFunctionObject *) func)->func_qualname,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment