Fix reference counting issues with new tests.
authorCraig Citro <craigcitro@gmail.com>
Fri, 29 Jan 2010 09:22:12 +0000 (01:22 -0800)
committerCraig Citro <craigcitro@gmail.com>
Fri, 29 Jan 2010 09:22:12 +0000 (01:22 -0800)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index 3f8b3dea5dabf3cdd3120942169dae1208e542e7..eb8f73f1011b15b5c3db4649293ffd0b91ad5dd5 100644 (file)
@@ -12,7 +12,8 @@ import Naming
 import Nodes
 from Nodes import Node
 import PyrexTypes
-from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type
+from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
+     unspecified_type
 from Builtin import list_type, tuple_type, set_type, dict_type, \
      unicode_type, str_type, bytes_type, type_type
 import Builtin
@@ -1365,19 +1366,20 @@ class NameNode(AtomicExprNode):
                     rhs.make_owned_reference(code)
                     if entry.is_cglobal:
                         code.put_gotref(self.py_result())
-                if self.use_managed_ref and not self.lhs_of_first_assignment:
-                    if entry.is_local and not Options.init_local_none:
-                        initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
-                        if initialized is True:
+                    if not self.lhs_of_first_assignment:
+                        if entry.is_local and not Options.init_local_none:
+                            initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
+                            if initialized is True:
+                                code.put_decref(self.result(), self.ctype())
+                            elif initialized is None:
+                                code.put_xdecref(self.result(), self.ctype())
+                        else:
                             code.put_decref(self.result(), self.ctype())
-                        elif initialized is None:
-                            code.put_xdecref(self.result(), self.ctype())
-                    else:
-                        code.put_decref(self.result(), self.ctype())
-                if self.use_managed_ref:
-                    if entry.is_cglobal or entry.in_closure:
+                    if entry.is_cglobal:
                         code.put_giveref(rhs.py_result())
-            code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
+
+            code.putln('%s = %s;' % (self.result(),
+                                     rhs.result_as(self.ctype())))
             if debug_disposal_code:
                 print("NameNode.generate_assignment_code:")
                 print("...generating post-assignment code for %s" % rhs)
index 1ee0ce13d4c00f57a220a4dc375f14e2d572f95c..67f795e35e1db1c36c7b92ff8f2b00ee4c3fd22a 100644 (file)
@@ -1022,9 +1022,13 @@ class FuncDefNode(StatNode, BlockNode):
         while genv.is_py_class_scope or genv.is_c_class_scope:
             genv = env.outer_scope
         if self.needs_closure:
-            lenv = ClosureScope(name = self.entry.name, scope_name = self.entry.cname, outer_scope = genv)
+            lenv = ClosureScope(name=self.entry.name,
+                                outer_scope = genv,
+                                scope_name=self.entry.cname)
         else:
-            lenv = LocalScope(name = self.entry.name, outer_scope = genv, parent_scope = env)
+            lenv = LocalScope(name=self.entry.name,
+                              outer_scope=genv,
+                              parent_scope=env)
         lenv.return_type = self.return_type
         type = self.entry.type
         if type.is_cfunction:
@@ -1078,7 +1082,7 @@ class FuncDefNode(StatNode, BlockNode):
         if lenv.is_closure_scope:
             code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
             code.putln(";")
-        if env.is_closure_scope and not lenv.is_closure_scope:
+        elif env.is_closure_scope:
             code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
             code.putln(";")
         self.generate_argument_declarations(lenv, code)
@@ -1091,9 +1095,8 @@ class FuncDefNode(StatNode, BlockNode):
                 init = " = NULL"
             code.putln(
                 "%s%s;" % 
-                    (self.return_type.declaration_code(
-                        Naming.retval_cname),
-                    init))
+                    (self.return_type.declaration_code(Naming.retval_cname),
+                     init))
         tempvardecl_code = code.insertion_point()
         self.generate_keyword_list(code)
         # ----- Extern library function declarations
@@ -1144,15 +1147,20 @@ class FuncDefNode(StatNode, BlockNode):
         # ----- Initialise local buffer auxiliary variables
         for entry in lenv.var_entries + lenv.arg_entries:
             if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
-                code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
+                code.putln("%s.buf = NULL;" %
+                           entry.buffer_aux.buffer_info_var.cname)
         # ----- Check and convert arguments
         self.generate_argument_type_tests(code)
         # ----- Acquire buffer arguments
         for entry in lenv.arg_entries:
             if entry.type.is_buffer:
-                Buffer.put_acquire_arg_buffer(entry, code, self.pos)        
-        # ----- Function body
+                Buffer.put_acquire_arg_buffer(entry, code, self.pos)
+
+        # -------------------------
+        # ----- Function body -----
+        # -------------------------
         self.body.generate_execution_code(code)
+
         # ----- Default return value
         code.putln("")
         if self.return_type.is_pyobject:
@@ -1203,10 +1211,7 @@ class FuncDefNode(StatNode, BlockNode):
             if err_val is None and default_retval:
                 err_val = default_retval
             if err_val is not None:
-                code.putln(
-                    "%s = %s;" % (
-                        Naming.retval_cname, 
-                        err_val))
+                code.putln("%s = %s;" % (Naming.retval_cname, err_val))
 
             if is_getbuffer_slot:
                 self.getbuffer_error_cleanup(code)
@@ -1233,15 +1238,19 @@ class FuncDefNode(StatNode, BlockNode):
                     entry.xdecref_cleanup = 1
         
         for entry in lenv.var_entries:
-            if entry.used and not entry.in_closure:
-                code.put_var_decref(entry)
+            if entry.type.is_pyobject:
+                if entry.used and not entry.in_closure:
+                    code.put_var_decref(entry)
+                elif entry.in_closure and self.needs_closure:
+                    code.put_giveref(entry.cname)
         # Decref any increfed args
         for entry in lenv.arg_entries:
             if entry.type.is_pyobject:
-                if entry.in_closure and not entry.assignments:
-                    code.put_var_incref(entry)
+                if entry.in_closure:
+                    if not entry.assignments:
+                        code.put_var_incref(entry)
                     code.put_var_giveref(entry)
-                elif not entry.in_closure and entry.assignments:
+                elif entry.assignments:
                     code.put_var_decref(entry)
         if self.needs_closure:
             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)