Commit c0c7651a authored by gsamain's avatar gsamain

Cypclass refcount

parent bd9b417b
...@@ -1962,7 +1962,7 @@ class CCodeWriter(object): ...@@ -1962,7 +1962,7 @@ class CCodeWriter(object):
entry.cname, dll_linkage=dll_linkage)) entry.cname, dll_linkage=dll_linkage))
if entry.init is not None: if entry.init is not None:
self.put_safe(" = %s" % entry.type.literal_code(entry.init)) self.put_safe(" = %s" % entry.type.literal_code(entry.init))
elif entry.type.is_pyobject: elif entry.type.is_pyobject or entry.type.is_cyp_class:
self.put(" = NULL") self.put(" = NULL")
self.putln(";") self.putln(";")
...@@ -1974,8 +1974,8 @@ class CCodeWriter(object): ...@@ -1974,8 +1974,8 @@ class CCodeWriter(object):
elif type.is_memoryviewslice: elif type.is_memoryviewslice:
from . import MemoryView from . import MemoryView
self.putln("%s = %s;" % (decl, MemoryView.memslice_entry_init)) self.putln("%s = %s;" % (decl, MemoryView.memslice_entry_init))
elif type.is_struct and type.is_extension_type and type.nogil: elif type.is_cyp_class:
self.putln("%s;" % decl) self.putln("%s = NULL;" % decl)
else: else:
self.putln("%s%s;" % (static and "static " or "", decl)) self.putln("%s%s;" % (static and "static " or "", decl))
......
...@@ -751,10 +751,11 @@ class ExprNode(Node): ...@@ -751,10 +751,11 @@ class ExprNode(Node):
If result is a pyobject, make sure we own a reference to it. If result is a pyobject, make sure we own a reference to it.
If the result is in a temp, it is already a new reference. If the result is in a temp, it is already a new reference.
""" """
if self.type.is_pyobject and not self.result_in_temp(): if not self.result_in_temp():
code.put_incref(self.result(), self.ctype()) if self.type.is_pyobject:
elif self.type.is_extension_type and not self.type.is_pyobject and not self.result_in_temp(): code.put_incref(self.result(), self.ctype())
code.put_cyincref(self.result()) elif self.type.is_cyp_class and "NULL" not in self.result():
code.put_cyincref(self.result())
def make_owned_memoryviewslice(self, code): def make_owned_memoryviewslice(self, code):
""" """
...@@ -802,8 +803,8 @@ class ExprNode(Node): ...@@ -802,8 +803,8 @@ class ExprNode(Node):
self.result(), have_gil=not self.in_nogil_context) self.result(), have_gil=not self.in_nogil_context)
code.putln("%s.memview = NULL;" % self.result()) code.putln("%s.memview = NULL;" % self.result())
code.putln("%s.data = NULL;" % self.result()) code.putln("%s.data = NULL;" % self.result())
elif self.type.is_extension_type and not self.type.is_pyobject: elif self.type.is_cyp_class:
code.put_cydecref(self.result()) code.put_cyxdecref(self.result())
else: else:
# Already done if self.is_temp # Already done if self.is_temp
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
...@@ -825,7 +826,7 @@ class ExprNode(Node): ...@@ -825,7 +826,7 @@ class ExprNode(Node):
elif self.type.is_memoryviewslice: elif self.type.is_memoryviewslice:
code.putln("%s.memview = NULL;" % self.result()) code.putln("%s.memview = NULL;" % self.result())
code.putln("%s.data = NULL;" % self.result()) code.putln("%s.data = NULL;" % self.result())
elif self.type.is_extension_type and not self.type.is_pyobject: elif self.type.is_cyp_class:
code.putln("%s = 0;" % self.result()) code.putln("%s = 0;" % self.result())
else: else:
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
...@@ -1790,7 +1791,7 @@ class ImagNode(AtomicExprNode): ...@@ -1790,7 +1791,7 @@ class ImagNode(AtomicExprNode):
float(self.value), float(self.value),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif self.type.is_extension_type: elif self.type.is_cyp_class:
code.put_cygotref(self.result()) code.put_cygotref(self.result())
...@@ -2271,7 +2272,7 @@ class NameNode(AtomicExprNode): ...@@ -2271,7 +2272,7 @@ class NameNode(AtomicExprNode):
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif entry.is_local and entry.type.is_extension_type and not entry.type.is_pyobject: elif entry.is_local and entry.type.is_cyp_class:
code.put_cygotref(self.result()) code.put_cygotref(self.result())
#pass #pass
# code.putln(entry.cname) # code.putln(entry.cname)
...@@ -2376,6 +2377,10 @@ class NameNode(AtomicExprNode): ...@@ -2376,6 +2377,10 @@ class NameNode(AtomicExprNode):
assigned = False assigned = False
if is_external_ref: if is_external_ref:
code.put_giveref(rhs.py_result()) code.put_giveref(rhs.py_result())
elif self.type.is_cyp_class:
code.put_cyxdecref(self.result())
if isinstance(rhs, NameNode):
rhs.make_owned_reference(code)
if not self.type.is_memoryviewslice: if not self.type.is_memoryviewslice:
if not assigned: if not assigned:
if overloaded_assignment: if overloaded_assignment:
...@@ -2493,7 +2498,7 @@ class NameNode(AtomicExprNode): ...@@ -2493,7 +2498,7 @@ class NameNode(AtomicExprNode):
else: else:
code.put_xdecref_memoryviewslice(self.entry.cname, code.put_xdecref_memoryviewslice(self.entry.cname,
have_gil=not self.nogil) have_gil=not self.nogil)
elif self.entry.type.is_extension_type: elif self.entry.type.is_cyp_class:
if not self.cf_is_null: if not self.cf_is_null:
if self.cf_maybe_null and not ignore_nonexisting: if self.cf_maybe_null and not ignore_nonexisting:
code.put_error_if_unbound(self.pos, self.entry) code.put_error_if_unbound(self.pos, self.entry)
...@@ -4104,7 +4109,7 @@ class IndexNode(_IndexingBaseNode): ...@@ -4104,7 +4109,7 @@ class IndexNode(_IndexingBaseNode):
code.error_goto_if(error_check % self.result(), self.pos))) code.error_goto_if(error_check % self.result(), self.pos)))
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif self.type.is_extension_type: elif self.type.is_cyp_class:
code.put_cygotref(self.result()) code.put_cygotref(self.result())
def generate_setitem_code(self, value_code, code): def generate_setitem_code(self, value_code, code):
...@@ -6009,7 +6014,7 @@ class SimpleCallNode(CallNode): ...@@ -6009,7 +6014,7 @@ class SimpleCallNode(CallNode):
if self.result(): if self.result():
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif self.type.is_extension_type: elif self.type.is_cyp_class:
code.put_cygotref(self.result()) code.put_cygotref(self.result())
if self.has_optional_args: if self.has_optional_args:
code.funcstate.release_temp(self.opt_arg_struct) code.funcstate.release_temp(self.opt_arg_struct)
...@@ -7007,6 +7012,8 @@ class AttributeNode(ExprNode): ...@@ -7007,6 +7012,8 @@ class AttributeNode(ExprNode):
self.op = "->" self.op = "->"
elif obj_type.is_reference and obj_type.is_fake_reference: elif obj_type.is_reference and obj_type.is_fake_reference:
self.op = "->" self.op = "->"
elif obj_type.is_cyp_class:
self.op = "->"
else: else:
self.op = "." self.op = "."
if obj_type.has_attributes: if obj_type.has_attributes:
...@@ -7261,6 +7268,11 @@ class AttributeNode(ExprNode): ...@@ -7261,6 +7268,11 @@ class AttributeNode(ExprNode):
from . import MemoryView from . import MemoryView
MemoryView.put_assign_to_memviewslice( MemoryView.put_assign_to_memviewslice(
select_code, rhs, rhs.result(), self.type, code) select_code, rhs, rhs.result(), self.type, code)
elif self.type.is_cyp_class:
rhs.make_owned_reference(code)
code.put_cygiveref(rhs.result())
code.put_cygotref(select_code)
code.put_cyxdecref(select_code)
if not self.type.is_memoryviewslice: if not self.type.is_memoryviewslice:
code.putln( code.putln(
...@@ -13426,6 +13438,8 @@ class CoerceToTempNode(CoercionNode): ...@@ -13426,6 +13438,8 @@ class CoerceToTempNode(CoercionNode):
elif self.type.is_memoryviewslice: elif self.type.is_memoryviewslice:
code.put_incref_memoryviewslice(self.result(), code.put_incref_memoryviewslice(self.result(),
not self.in_nogil_context) not self.in_nogil_context)
elif self.type.is_cyp_class:
code.put_cyincref(self.result())
class ProxyNode(CoercionNode): class ProxyNode(CoercionNode):
""" """
......
...@@ -960,7 +960,7 @@ class CArgDeclNode(Node): ...@@ -960,7 +960,7 @@ class CArgDeclNode(Node):
code.putln("%s = %s;" % (target, result)) code.putln("%s = %s;" % (target, result))
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_giveref(default.result()) code.put_giveref(default.result())
elif self.type.is_extension_type: elif self.type.is_cyp_class:
code.put_cygiveref(default.result()) code.put_cygiveref(default.result())
default.generate_post_assignment_code(code) default.generate_post_assignment_code(code)
default.free_temps(code) default.free_temps(code)
...@@ -1860,7 +1860,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1860,7 +1860,7 @@ class FuncDefNode(StatNode, BlockNode):
# Initialize the return variable __pyx_r # Initialize the return variable __pyx_r
init = "" init = ""
if not self.return_type.is_void: if not self.return_type.is_void:
if self.return_type.is_pyobject: if self.return_type.is_pyobject or self.return_type.is_cyp_class:
init = " = NULL" init = " = NULL"
elif self.return_type.is_memoryviewslice: elif self.return_type.is_memoryviewslice:
init = ' = ' + MemoryView.memslice_entry_init init = ' = ' + MemoryView.memslice_entry_init
...@@ -1994,7 +1994,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1994,7 +1994,7 @@ class FuncDefNode(StatNode, BlockNode):
elif is_cdef and entry.type.is_memoryviewslice and len(entry.cf_assignments) > 1: elif is_cdef and entry.type.is_memoryviewslice and len(entry.cf_assignments) > 1:
code.put_incref_memoryviewslice(entry.cname, have_gil=code.funcstate.gil_owned) code.put_incref_memoryviewslice(entry.cname, have_gil=code.funcstate.gil_owned)
# We have to Cy_INCREF the nogil classes (ccdef'ed ones) # We have to Cy_INCREF the nogil classes (ccdef'ed ones)
elif entry.type.is_extension_type and not entry.type.is_pyobject and len(entry.cf_assignments) > 1: elif entry.type.is_cyp_class and len(entry.cf_assignments) > 1:
code.put_cyincref(entry.cname) code.put_cyincref(entry.cname)
for entry in lenv.var_entries: for entry in lenv.var_entries:
if entry.is_arg and len(entry.cf_assignments) > 1 and not entry.in_closure: if entry.is_arg and len(entry.cf_assignments) > 1 and not entry.in_closure:
...@@ -2147,9 +2147,11 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2147,9 +2147,11 @@ class FuncDefNode(StatNode, BlockNode):
code.put_var_xdecref(entry) code.put_var_xdecref(entry)
else: else:
code.put_var_decref(entry) code.put_var_decref(entry)
elif entry.type.is_extension_type and not entry.type.is_pyobject and \ elif entry.type.is_cyp_class and \
(not entry.is_arg or len(entry.cf_assignments) > 1): (not entry.is_arg or len(entry.cf_assignments) > 1):
code.put_cydecref(entry.cname) # We must check for NULL because it is possible to have
# NULL as a valid cypclass (with a typecast)
code.put_cyxdecref(entry.cname)
# Decref any increfed args # Decref any increfed args
for entry in lenv.arg_entries: for entry in lenv.arg_entries:
...@@ -2162,8 +2164,10 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2162,8 +2164,10 @@ class FuncDefNode(StatNode, BlockNode):
# functions, but not borrowed slices from cdef functions. # functions, but not borrowed slices from cdef functions.
code.put_xdecref_memoryviewslice(entry.cname, code.put_xdecref_memoryviewslice(entry.cname,
have_gil=not lenv.nogil) have_gil=not lenv.nogil)
elif entry.type.is_extension_type and not entry.type.is_pyobject and len(entry.cf_assignments) > 1: elif entry.type.is_cyp_class and len(entry.cf_assignments) > 1:
code.put_cydecref(entry.cname) # We must check for NULL because it is possible to have
# NULL as a valid cypclass (with a typecast)
code.put_cyxdecref(entry.cname)
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)
...@@ -2177,7 +2181,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2177,7 +2181,7 @@ class FuncDefNode(StatNode, BlockNode):
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname)) code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
# We can always return a CythonExtensionType as it is nogil-compliant # We can always return a CythonExtensionType as it is nogil-compliant
if self.return_type.is_extension_type and not self.return_type.is_pyobject: if self.return_type.is_cyp_class:
code.put_cyxgiveref(Naming.retval_cname) code.put_cyxgiveref(Naming.retval_cname)
if self.entry.is_special and self.entry.name == "__hash__": if self.entry.is_special and self.entry.name == "__hash__":
...@@ -6143,7 +6147,7 @@ class ReturnStatNode(StatNode): ...@@ -6143,7 +6147,7 @@ class ReturnStatNode(StatNode):
# Use specialised default handling for "return None". # Use specialised default handling for "return None".
value = None value = None
if self.return_type.is_extension_type and not self.return_type.is_pyobject: if self.return_type.is_cyp_class:
code.put_cyxdecref(Naming.retval_cname) code.put_cyxdecref(Naming.retval_cname)
if value: if value:
......
...@@ -198,12 +198,12 @@ class ResultRefNode(AtomicExprNode): ...@@ -198,12 +198,12 @@ class ResultRefNode(AtomicExprNode):
pass pass
def generate_assignment_code(self, rhs, code, overloaded_assignment=False): def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
if self.type.is_pyobject or self.type.is_extension_type: if self.type.is_pyobject or self.type.is_cyp_class:
rhs.make_owned_reference(code) rhs.make_owned_reference(code)
if not self.lhs_of_first_assignment: if not self.lhs_of_first_assignment:
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_decref(self.result(), self.ctype()) code.put_decref(self.result(), self.ctype())
elif self.type.is_extension_type: elif self.type.is_cyp_class:
code.put_cydecref(self.result()) code.put_cydecref(self.result())
code.putln('%s = %s;' % ( code.putln('%s = %s;' % (
self.result(), self.result(),
...@@ -251,7 +251,7 @@ class LetNodeMixin: ...@@ -251,7 +251,7 @@ class LetNodeMixin:
else: else:
if self.temp_type.is_pyobject: if self.temp_type.is_pyobject:
code.put_decref_clear(self.temp, self.temp_type) code.put_decref_clear(self.temp, self.temp_type)
elif self.temp_type.is_extension_type: elif self.temp_type.is_cyp_class:
pass pass
#code.put_decref_clear(self.temp, self.temp_type) #code.put_decref_clear(self.temp, self.temp_type)
code.funcstate.release_temp(self.temp) code.funcstate.release_temp(self.temp)
......
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