diff options
| author | Stefan Behnel <stefan_ml@behnel.de> | 2020-04-11 19:16:55 +0200 |
|---|---|---|
| committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-04-11 19:16:55 +0200 |
| commit | c964bfd3c64d3e0816dd6ac1d61f974e7f74aed5 (patch) | |
| tree | 1d9b4a566baa0ff4a9fcfc3288110b47167165eb | |
| parent | 4095f032ef78dbe9ccefd6a19802da56e05d99f4 (diff) | |
| download | cython-c964bfd3c64d3e0816dd6ac1d61f974e7f74aed5.tar.gz | |
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.
| -rw-r--r-- | Cython/Compiler/ExprNodes.py | 4 | ||||
| -rw-r--r-- | Cython/Utility/CythonFunction.c | 79 |
2 files changed, 52 insertions, 31 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 829baeaf0..bfd518ffb 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -9357,11 +9357,11 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin): if self.specialized_cpdefs or self.is_specialization: code.globalstate.use_utility_code( UtilityCode.load_cached("FusedFunction", "CythonFunction.c")) - constructor = "__pyx_FusedFunction_NewEx" + constructor = "__pyx_FusedFunction_New" else: code.globalstate.use_utility_code( UtilityCode.load_cached("CythonFunction", "CythonFunction.c")) - constructor = "__Pyx_CyFunction_NewEx" + constructor = "__Pyx_CyFunction_New" if self.code_object: code_object_result = self.code_object.py_result() diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c index e6950626e..5bdb90e87 100644 --- a/Cython/Utility/CythonFunction.c +++ b/Cython/Utility/CythonFunction.c @@ -1,6 +1,6 @@ +//////////////////// CythonFunctionShared.proto //////////////////// -//////////////////// CythonFunction.proto //////////////////// #define __Pyx_CyFunction_USED 1 #define __Pyx_CYFUNCTION_STATICMETHOD 0x01 @@ -55,10 +55,7 @@ static PyTypeObject *__pyx_CyFunctionType = 0; #define __Pyx_CyFunction_Check(obj) (__Pyx_TypeCheck(obj, __pyx_CyFunctionType)) -#define __Pyx_CyFunction_NewEx(ml, flags, qualname, closure, module, globals, code) \ - __Pyx_CyFunction_New((PyTypeObject *)__pyx_CyFunctionType, ml, flags, qualname, closure, module, globals, code) - -static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *closure, PyObject *module, PyObject *globals, @@ -88,7 +85,7 @@ static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, #endif #endif -//////////////////// CythonFunction //////////////////// +//////////////////// CythonFunctionShared //////////////////// //@substitute: naming //@requires: CommonStructures.c::FetchCommonType //@requires: ObjectHandling.c::PyMethodNew @@ -472,11 +469,9 @@ static PyMethodDef __pyx_CyFunction_methods[] = { #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) #endif - -static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { - __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type); - if (op == NULL) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + if (unlikely(op == NULL)) return NULL; op->flags = flags; __Pyx_CyFunction_weakreflist(op) = NULL; @@ -525,7 +520,6 @@ static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int f return NULL; } #endif - PyObject_GC_Track(op); return (PyObject *) op; } @@ -970,11 +964,36 @@ static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, Py 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 //////////////////// static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj);/*proto*/ //////////////////// CyFunctionClassCell //////////////////// -//@requires: CythonFunction +//@requires: CythonFunctionShared static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) { Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions); @@ -997,17 +1016,16 @@ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *class return 0; } + //////////////////// FusedFunction.proto //////////////////// + typedef struct { __pyx_CyFunctionObject func; PyObject *__signatures__; PyObject *self; } __pyx_FusedFunctionObject; -#define __pyx_FusedFunction_NewEx(ml, flags, qualname, closure, module, globals, code) \ - __pyx_FusedFunction_New((PyTypeObject *)__pyx_FusedFunctionType, ml, flags, qualname, closure, module, globals, code) -static PyObject *__pyx_FusedFunction_New(PyTypeObject *type, - PyMethodDef *ml, int flags, +static PyObject *__pyx_FusedFunction_New(PyMethodDef *ml, int flags, PyObject *qualname, PyObject *closure, PyObject *module, PyObject *globals, PyObject *code); @@ -1021,23 +1039,26 @@ static int __pyx_FusedFunction_init(void); #define __Pyx_FusedFunction_USED //////////////////// FusedFunction //////////////////// -//@requires: CythonFunction +//@requires: CythonFunctionShared static PyObject * -__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, +__pyx_FusedFunction_New(PyMethodDef *ml, int flags, PyObject *qualname, PyObject *closure, PyObject *module, PyObject *globals, PyObject *code) { - __pyx_FusedFunctionObject *fusedfunc = - (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname, - closure, module, globals, code); - if (!fusedfunc) - return NULL; - - fusedfunc->__signatures__ = NULL; - fusedfunc->self = NULL; - return (PyObject *) fusedfunc; + PyObject *op = __Pyx_CyFunction_Init( + // __pyx_CyFunctionObject is correct below since that's the cast that we want. + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_FusedFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + __pyx_FusedFunctionObject *fusedfunc = (__pyx_FusedFunctionObject *) op; + fusedfunc->__signatures__ = NULL; + fusedfunc->self = NULL; + PyObject_GC_Track(op); + } + return op; } static void @@ -1084,7 +1105,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type) if (obj == Py_None) obj = NULL; - meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx( + meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_New( ((PyCFunctionObject *) func)->m_ml, ((__pyx_CyFunctionObject *) func)->flags, ((__pyx_CyFunctionObject *) func)->func_qualname, |
