refnanny: Make generated slot functions work.
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Mon, 12 Jan 2009 15:25:49 +0000 (16:25 +0100)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Mon, 12 Jan 2009 15:25:49 +0000 (16:25 +0100)
Cython/Compiler/Code.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py

index 62dabaddc8374257aab3c6fd890deb6795a91f8d..abb712cfb4d44e809e0ad50c125572c1f6377fa4 100644 (file)
@@ -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
index 00b70e1f1e654f081c4470c36b859b148b016ddd..488da6ff4cc01f230fde4b4c007ab1a221d16eec 100644 (file)
@@ -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")
index a821f8c08407d45b01e666397d2e8b93888caf94..dbbe176647862d286830ee0e73cb1e96c41ae375 100644 (file)
@@ -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)