From 1fdb965c7279c0e6d92920fa97fafe6ace88c3c0 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Fri, 30 Jan 2009 10:54:11 +0100 Subject: [PATCH] Refnanny fixes; it now runs the test suite correctly. --- Cython/Compiler/Buffer.py | 4 ++-- Cython/Compiler/ExprNodes.py | 4 ++++ Cython/Compiler/Nodes.py | 11 +++++++++-- Cython/Runtime/refnanny.pyx | 29 +++++++++++++++++++++++------ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py index 8fb4c200..7934ea34 100644 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@ -305,7 +305,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type, for i in range(3)] code.putln('PyErr_Fetch(&%s, &%s, &%s);' % (type, value, tb)) code.putln('if (%s) {' % code.unlikely("%s == -1" % (getbuffer % lhs_cname))) - code.putln('Py_XDECREF(%s); Py_XDECREF(%s); Py_XDECREF(%s);' % (type, value, tb)) + code.putln('Py_XDECREF(%s); Py_XDECREF(%s); Py_XDECREF(%s);' % (type, value, tb)) # Do not refnanny these! code.globalstate.use_utility_code(raise_buffer_fallback_code) code.putln('__Pyx_RaiseBufferFallbackError();') code.putln('} else {') @@ -323,7 +323,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type, # In this case, auxiliary vars should be set up right in initialization to a zero-buffer, # so it suffices to set the buf field to NULL. code.putln('if (%s) {' % code.unlikely("%s == -1" % (getbuffer % rhs_cname))) - code.putln('%s = %s; Py_INCREF(Py_None); %s.buf = NULL;' % + code.putln('%s = %s; __Pyx_INCREF(Py_None); %s.buf = NULL;' % (lhs_cname, PyrexTypes.typecast(buffer_type, PyrexTypes.py_object_type, "Py_None"), bufstruct)) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 0c4d8d89..0fba3570 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1878,10 +1878,12 @@ class IndexNode(ExprNode): ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False) rhs_code = rhs.result() code.putln("%s = %s;" % (ptr, ptrexpr)) + code.put_gotref("*%s" % ptr) code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % ( ptr, rhs_code )) code.putln("*%s %s= %s;" % (ptr, op, rhs_code)) + code.put_giveref("*%s" % ptr) code.funcstate.release_temp(ptr) else: # Simple case @@ -2887,6 +2889,7 @@ class AttributeNode(NewTempExprNode): if self.type.is_pyobject: rhs.make_owned_reference(code) code.put_giveref(rhs.py_result()) + code.put_gotref(select_code) code.put_decref(select_code, self.ctype()) code.putln( "%s = %s;" % ( @@ -3354,6 +3357,7 @@ class SetNode(NewTempExprNode): "%s = PySet_New(0); %s" % ( self.result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) for arg in self.args: arg.generate_evaluation_code(code) code.putln( diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index bb08311a..88c4f3f9 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1254,16 +1254,20 @@ class FuncDefNode(StatNode, BlockNode): # the following line should be removed when this bug is fixed. code.putln("if (%s == NULL) return 0;" % info) code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info) + code.put_giveref("%s->obj" % info) # Do not refnanny object within structs def getbuffer_error_cleanup(self, code): info = self.local_scope.arg_entries[1].cname + code.put_gotref("%s->obj" % info) code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" % (info, info)) def getbuffer_normal_cleanup(self, code): info = self.local_scope.arg_entries[1].cname - code.putln("if (%s->obj == Py_None) { __Pyx_DECREF(Py_None); %s->obj = NULL; }" % - (info, info)) + code.putln("if (%s->obj == Py_None) {" % info) + code.put_gotref("Py_None") + code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info) + code.putln("}") class CFuncDefNode(FuncDefNode): # C function definition. @@ -2014,6 +2018,8 @@ class DefNode(FuncDefNode): code.putln("if (unlikely(!%s)) return %s;" % ( self.starstar_arg.entry.cname, self.error_value())) self.starstar_arg.entry.xdecref_cleanup = 0 + code.put_gotref(self.starstar_arg.entry.cname) + if self.star_arg: code.put_incref(Naming.args_cname, py_object_type) @@ -3234,6 +3240,7 @@ class ExecStatNode(StatNode): arg.free_temps(code) code.putln( code.error_goto_if_null(self.temp_result, self.pos)) + code.put_gotref(self.temp_result) code.put_decref_clear(self.temp_result, py_object_type) def annotate(self, code): diff --git a/Cython/Runtime/refnanny.pyx b/Cython/Runtime/refnanny.pyx index b9c3c942..c5bea9ee 100644 --- a/Cython/Runtime/refnanny.pyx +++ b/Cython/Runtime/refnanny.pyx @@ -60,15 +60,27 @@ cdef public void __Pyx_Refnanny_GOTREF(void* ctx, object obj, int lineno): cdef exc.PyObject* type, *value, *tb if ctx == NULL: return exc.PyErr_Fetch(&type, &value, &tb) - (ctx).regref(obj, lineno) - exc.PyErr_Restore(type, value, tb) + try: + (ctx).regref(obj, lineno) + exc.PyErr_Restore(type, value, tb) + except: + Py_XDECREF(type) + Py_XDECREF(value) + Py_XDECREF(tb) + raise cdef public void __Pyx_Refnanny_GIVEREF(void* ctx, object obj, int lineno): cdef exc.PyObject* type, *value, *tb if ctx == NULL: return exc.PyErr_Fetch(&type, &value, &tb) - (ctx).delref(obj, lineno) - exc.PyErr_Restore(type, value, tb) + try: + (ctx).delref(obj, lineno) + exc.PyErr_Restore(type, value, tb) + except: + Py_XDECREF(type) + Py_XDECREF(value) + Py_XDECREF(tb) + raise cdef public void __Pyx_Refnanny_INCREF(void* ctx, object obj, int lineno): Py_INCREF(obj) @@ -88,9 +100,14 @@ cdef public int __Pyx_Refnanny_FinishContext(void* ctx) except -1: obj = ctx try: obj.end() + exc.PyErr_Restore(type, value, tb) + except Exception, e: + Py_XDECREF(type) + Py_XDECREF(value) + Py_XDECREF(tb) + raise finally: - Py_DECREF(obj) - exc.PyErr_Restore(type, value, tb) + Py_XDECREF(obj) return 0 -- 2.26.2