Commit da4566a3 authored by Craig Citro's avatar Craig Citro

Fix reference counting issues with new tests.

parent b645c385
...@@ -12,7 +12,8 @@ import Naming ...@@ -12,7 +12,8 @@ import Naming
import Nodes import Nodes
from Nodes import Node from Nodes import Node
import PyrexTypes 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, \ from Builtin import list_type, tuple_type, set_type, dict_type, \
unicode_type, str_type, bytes_type, type_type unicode_type, str_type, bytes_type, type_type
import Builtin import Builtin
...@@ -1365,19 +1366,20 @@ class NameNode(AtomicExprNode): ...@@ -1365,19 +1366,20 @@ class NameNode(AtomicExprNode):
rhs.make_owned_reference(code) rhs.make_owned_reference(code)
if entry.is_cglobal: if entry.is_cglobal:
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
if self.use_managed_ref and not self.lhs_of_first_assignment: if not self.lhs_of_first_assignment:
if entry.is_local and not Options.init_local_none: if entry.is_local and not Options.init_local_none:
initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos) initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
if initialized is True: 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()) code.put_decref(self.result(), self.ctype())
elif initialized is None: if entry.is_cglobal:
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:
code.put_giveref(rhs.py_result()) 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: if debug_disposal_code:
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
print("...generating post-assignment code for %s" % rhs) print("...generating post-assignment code for %s" % rhs)
......
...@@ -1022,9 +1022,13 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1022,9 +1022,13 @@ class FuncDefNode(StatNode, BlockNode):
while genv.is_py_class_scope or genv.is_c_class_scope: while genv.is_py_class_scope or genv.is_c_class_scope:
genv = env.outer_scope genv = env.outer_scope
if self.needs_closure: 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: 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 lenv.return_type = self.return_type
type = self.entry.type type = self.entry.type
if type.is_cfunction: if type.is_cfunction:
...@@ -1078,7 +1082,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1078,7 +1082,7 @@ class FuncDefNode(StatNode, BlockNode):
if lenv.is_closure_scope: if lenv.is_closure_scope:
code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname)) code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
code.putln(";") 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.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
code.putln(";") code.putln(";")
self.generate_argument_declarations(lenv, code) self.generate_argument_declarations(lenv, code)
...@@ -1091,9 +1095,8 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1091,9 +1095,8 @@ class FuncDefNode(StatNode, BlockNode):
init = " = NULL" init = " = NULL"
code.putln( code.putln(
"%s%s;" % "%s%s;" %
(self.return_type.declaration_code( (self.return_type.declaration_code(Naming.retval_cname),
Naming.retval_cname), init))
init))
tempvardecl_code = code.insertion_point() tempvardecl_code = code.insertion_point()
self.generate_keyword_list(code) self.generate_keyword_list(code)
# ----- Extern library function declarations # ----- Extern library function declarations
...@@ -1144,15 +1147,20 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1144,15 +1147,20 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Initialise local buffer auxiliary variables # ----- Initialise local buffer auxiliary variables
for entry in lenv.var_entries + lenv.arg_entries: for entry in lenv.var_entries + lenv.arg_entries:
if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used: 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 # ----- Check and convert arguments
self.generate_argument_type_tests(code) self.generate_argument_type_tests(code)
# ----- Acquire buffer arguments # ----- Acquire buffer arguments
for entry in lenv.arg_entries: for entry in lenv.arg_entries:
if entry.type.is_buffer: if entry.type.is_buffer:
Buffer.put_acquire_arg_buffer(entry, code, self.pos) Buffer.put_acquire_arg_buffer(entry, code, self.pos)
# ----- Function body
# -------------------------
# ----- Function body -----
# -------------------------
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
# ----- Default return value # ----- Default return value
code.putln("") code.putln("")
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
...@@ -1203,10 +1211,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1203,10 +1211,7 @@ class FuncDefNode(StatNode, BlockNode):
if err_val is None and default_retval: if err_val is None and default_retval:
err_val = default_retval err_val = default_retval
if err_val is not None: if err_val is not None:
code.putln( code.putln("%s = %s;" % (Naming.retval_cname, err_val))
"%s = %s;" % (
Naming.retval_cname,
err_val))
if is_getbuffer_slot: if is_getbuffer_slot:
self.getbuffer_error_cleanup(code) self.getbuffer_error_cleanup(code)
...@@ -1233,15 +1238,19 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1233,15 +1238,19 @@ class FuncDefNode(StatNode, BlockNode):
entry.xdecref_cleanup = 1 entry.xdecref_cleanup = 1
for entry in lenv.var_entries: for entry in lenv.var_entries:
if entry.used and not entry.in_closure: if entry.type.is_pyobject:
code.put_var_decref(entry) 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 # Decref any increfed args
for entry in lenv.arg_entries: for entry in lenv.arg_entries:
if entry.type.is_pyobject: if entry.type.is_pyobject:
if entry.in_closure and not entry.assignments: if entry.in_closure:
code.put_var_incref(entry) if not entry.assignments:
code.put_var_incref(entry)
code.put_var_giveref(entry) code.put_var_giveref(entry)
elif not entry.in_closure and entry.assignments: elif entry.assignments:
code.put_var_decref(entry) code.put_var_decref(entry)
if self.needs_closure: if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type) code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment