From da4566a33054262ed33061d08ff0d6cf48948253 Mon Sep 17 00:00:00 2001 From: Craig Citro Date: Fri, 29 Jan 2010 01:22:12 -0800 Subject: [PATCH] Fix reference counting issues with new tests. --- Cython/Compiler/ExprNodes.py | 26 +++++++++++---------- Cython/Compiler/Nodes.py | 45 +++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 3f8b3dea..eb8f73f1 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 1ee0ce13..67f795e3 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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) -- 2.26.2