Refnanny fixes; it now runs the test suite correctly.
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 30 Jan 2009 09:54:11 +0000 (10:54 +0100)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 30 Jan 2009 09:54:11 +0000 (10:54 +0100)
Cython/Compiler/Buffer.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Runtime/refnanny.pyx

index 8fb4c2001d44f2b724c8fb4913962a9287d8f50c..7934ea34a2f77e0fc94ede702aca423e4ca2d962 100644 (file)
@@ -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))
index 0c4d8d89ee0836446eeb707a7315f84b7932240e..0fba35709476b909388878a24864331f64954d51 100644 (file)
@@ -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(
index bb08311a724fad49a546325d4213b9b43dc03eff..88c4f3f949d3120ea1097da1b84fa6e7eaf15ec8 100644 (file)
@@ -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):
index b9c3c94286acae73349b038dcb75ac39b8a5874f..c5bea9eed9a6a6ba52726af202675eca60a14963 100644 (file)
@@ -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)
-    (<object>ctx).regref(obj, lineno)
-    exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+    try:
+        (<object>ctx).regref(obj, lineno)
+        exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+    except:
+        Py_XDECREF(<object>type)
+        Py_XDECREF(<object>value)
+        Py_XDECREF(<object>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)
-    (<object>ctx).delref(obj, lineno)
-    exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+    try:
+        (<object>ctx).delref(obj, lineno)
+        exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+    except:
+        Py_XDECREF(<object>type)
+        Py_XDECREF(<object>value)
+        Py_XDECREF(<object>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 = <object>ctx
     try:
         obj.end()
+        exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+    except Exception, e:
+        Py_XDECREF(<object>type)
+        Py_XDECREF(<object>value)
+        Py_XDECREF(<object>tb)
+        raise
     finally:
-        Py_DECREF(obj)
-    exc.PyErr_Restore(<object>type, <object>value, <object>tb)
+        Py_XDECREF(obj)
     return 0