From 96da7399753749f33457aeb487909361867503d7 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Mon, 12 Jan 2009 16:25:49 +0100 Subject: [PATCH] refnanny: Make generated slot functions work. --- Cython/Compiler/Code.py | 64 +++++++++++++++++++++++++---------- Cython/Compiler/ModuleNode.py | 17 ++++------ Cython/Compiler/Nodes.py | 15 ++++---- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index 62dabadd..abb712cf 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -747,11 +747,17 @@ class CCodeWriter(object): def put_xgiveref(self, cname): self.putln("__Pyx_XGIVEREF(%s);" % cname) - def put_incref(self, cname, type): - self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type)) + def put_incref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type)) - def put_decref(self, cname, type): - self.putln("__Pyx_DECREF(%s);" % self.as_pyobject(cname, type)) + def put_decref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_DECREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_DECREF(%s);" % self.as_pyobject(cname, type)) def put_var_gotref(self, entry): if entry.type.is_pyobject: @@ -769,17 +775,27 @@ class CCodeWriter(object): if entry.type.is_pyobject: self.putln("__Pyx_INCREF(%s);" % self.entry_as_pyobject(entry)) - def put_decref_clear(self, cname, type): - self.putln("__Pyx_DECREF(%s); %s = 0;" % ( - typecast(py_object_type, type, cname), cname)) - #self.as_pyobject(cname, type), cname)) + def put_decref_clear(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_DECREF(%s); %s = 0;" % ( + typecast(py_object_type, type, cname), cname)) + else: + self.putln("Py_DECREF(%s); %s = 0;" % ( + typecast(py_object_type, type, cname), cname)) - def put_xdecref(self, cname, type): - self.putln("__Pyx_XDECREF(%s);" % self.as_pyobject(cname, type)) + def put_xdecref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_XDECREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_XDECREF(%s);" % self.as_pyobject(cname, type)) - def put_xdecref_clear(self, cname, type): - self.putln("__Pyx_XDECREF(%s); %s = 0;" % ( - self.as_pyobject(cname, type), cname)) + def put_xdecref_clear(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_XDECREF(%s); %s = 0;" % ( + self.as_pyobject(cname, type), cname)) + else: + self.putln("Py_XDECREF(%s); %s = 0;" % ( + self.as_pyobject(cname, type), cname)) def put_var_decref(self, entry): if entry.type.is_pyobject: @@ -818,15 +834,18 @@ class CCodeWriter(object): for entry in entries: self.put_var_xdecref_clear(entry) - def put_init_to_py_none(self, cname, type): + def put_init_to_py_none(self, cname, type, nanny=True): py_none = typecast(type, py_object_type, "Py_None") - self.putln("%s = %s; __Pyx_INCREF(Py_None);" % (cname, py_none)) + if nanny: + self.putln("%s = %s; __Pyx_INCREF(Py_None);" % (cname, py_none)) + else: + self.putln("%s = %s; Py_INCREF(Py_None);" % (cname, py_none)) - def put_init_var_to_py_none(self, entry, template = "%s"): + def put_init_var_to_py_none(self, entry, template = "%s", nanny=True): code = template % entry.cname #if entry.type.is_extension_type: # code = "((PyObject*)%s)" % code - self.put_init_to_py_none(code, entry.type) + self.put_init_to_py_none(code, entry.type, nanny) def put_pymethoddef(self, entry, term): if entry.doc: @@ -894,6 +913,17 @@ class CCodeWriter(object): def lookup_filename(self, filename): return self.globalstate.lookup_filename(filename) + def put_setup_refcount_context(self, name): + self.putln('__Pyx_SetupRefcountContext("%s");' % name) + + def put_finish_refcount_context(self, pos, name, retval_cname, err_val): + self.putln('if (__Pyx_FinishRefcountContext() == -1) {') + self.putln(self.set_error_info(pos)) + self.putln('__Pyx_AddTraceback("%s");' % name) + if err_val is not None: + self.putln('%s = %s;' % (retval_cname, err_val)) + self.putln('}') + class PyrexCodeWriter: # f file output file diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 00b70e1f..488da6ff 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -906,7 +906,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if entry.name == "__weakref__": code.putln("p->%s = 0;" % entry.cname) else: - code.put_init_var_to_py_none(entry, "p->%s") + code.put_init_var_to_py_none(entry, "p->%s", nanny=False) entry = scope.lookup_here("__new__") if entry and entry.is_special: if entry.trivial_signature: @@ -916,7 +916,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln( "if (%s(%s) < 0) {" % (entry.func_cname, cinit_args)) - code.put_decref_clear("o", py_object_type); + code.put_decref_clear("o", py_object_type, nanny=False); code.putln( "}") code.putln( @@ -945,7 +945,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if weakref_slot in scope.var_entries: code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") for entry in py_attrs: - code.put_xdecref("p->%s" % entry.cname, entry.type) + code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False) if base_type: tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) if tp_dealloc is None: @@ -1054,7 +1054,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): for entry in py_attrs: name = "p->%s" % entry.cname code.putln("tmp = ((PyObject*)%s);" % name) - code.put_init_to_py_none(name, entry.type) + code.put_init_to_py_none(name, entry.type, nanny=False) code.putln("Py_XDECREF(tmp);") code.putln( "return 0;") @@ -1591,7 +1591,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("PyObject* %s;" % Naming.retval_cname) tempdecl_code = code.insertion_point() - code.putln('__Pyx_SetupRefcountContext("%s");' % header3) + code.put_setup_refcount_context(header3) code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))); @@ -1646,11 +1646,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): env.use_utility_code(Nodes.traceback_utility_code) code.putln("%s = NULL;" % Naming.retval_cname) code.put_label(code.return_label) - code.putln('if (__Pyx_FinishRefcountContext() == -1) {') - code.putln(code.set_error_info(self.pos)) - code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name) - code.putln('%s = NULL;' % Naming.retval_cname) - code.putln('}') + code.put_finish_refcount_context(self.pos, env.qualified_name, + "NULL", Naming.retval_cname) code.putln("#if PY_MAJOR_VERSION < 3") code.putln("return;") code.putln("#else") diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index a821f8c0..dbbe1766 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1023,7 +1023,7 @@ class FuncDefNode(StatNode, BlockNode): # ----- Automatic lead-ins for certain special functions if is_getbuffer_slot: self.getbuffer_init(code) - code.putln('__Pyx_SetupRefcountContext("%s");' % self.entry.name) + code.put_setup_refcount_context(self.entry.name) # ----- Fetch arguments self.generate_argument_parsing_code(env, code) # If an argument is assigned to in the body, we must @@ -1144,14 +1144,11 @@ class FuncDefNode(StatNode, BlockNode): err_val = default_retval if self.return_type.is_pyobject: code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname)) - if err_val is None: - code.putln('__Pyx_FinishRefcountContext();') - else: - code.putln('if (__Pyx_FinishRefcountContext() == -1) {') - code.putln(code.set_error_info(self.pos)) - code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name) - code.putln('%s = %s;' % (Naming.retval_cname, err_val)) - code.putln('}') + + code.put_finish_refcount_context(self.pos, + self.entry.qualified_name, + Naming.retval_cname, + err_val) if not self.return_type.is_void: code.putln("return %s;" % Naming.retval_cname) -- 2.26.2