Commit 96da7399 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

refnanny: Make generated slot functions work.

parent 778f29a7
...@@ -747,11 +747,17 @@ class CCodeWriter(object): ...@@ -747,11 +747,17 @@ class CCodeWriter(object):
def put_xgiveref(self, cname): def put_xgiveref(self, cname):
self.putln("__Pyx_XGIVEREF(%s);" % cname) self.putln("__Pyx_XGIVEREF(%s);" % cname)
def put_incref(self, cname, type): def put_incref(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type)) 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): def put_decref(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_DECREF(%s);" % self.as_pyobject(cname, type)) 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): def put_var_gotref(self, entry):
if entry.type.is_pyobject: if entry.type.is_pyobject:
...@@ -769,17 +775,27 @@ class CCodeWriter(object): ...@@ -769,17 +775,27 @@ class CCodeWriter(object):
if entry.type.is_pyobject: if entry.type.is_pyobject:
self.putln("__Pyx_INCREF(%s);" % self.entry_as_pyobject(entry)) self.putln("__Pyx_INCREF(%s);" % self.entry_as_pyobject(entry))
def put_decref_clear(self, cname, type): def put_decref_clear(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_DECREF(%s); %s = 0;" % ( self.putln("__Pyx_DECREF(%s); %s = 0;" % (
typecast(py_object_type, type, cname), cname)) typecast(py_object_type, type, cname), cname))
#self.as_pyobject(cname, type), cname)) else:
self.putln("Py_DECREF(%s); %s = 0;" % (
typecast(py_object_type, type, cname), cname))
def put_xdecref(self, cname, type): def put_xdecref(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_XDECREF(%s);" % self.as_pyobject(cname, type)) 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): def put_xdecref_clear(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_XDECREF(%s); %s = 0;" % ( self.putln("__Pyx_XDECREF(%s); %s = 0;" % (
self.as_pyobject(cname, type), cname)) 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): def put_var_decref(self, entry):
if entry.type.is_pyobject: if entry.type.is_pyobject:
...@@ -818,15 +834,18 @@ class CCodeWriter(object): ...@@ -818,15 +834,18 @@ class CCodeWriter(object):
for entry in entries: for entry in entries:
self.put_var_xdecref_clear(entry) 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") py_none = typecast(type, py_object_type, "Py_None")
if nanny:
self.putln("%s = %s; __Pyx_INCREF(Py_None);" % (cname, py_none)) 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 code = template % entry.cname
#if entry.type.is_extension_type: #if entry.type.is_extension_type:
# code = "((PyObject*)%s)" % code # 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): def put_pymethoddef(self, entry, term):
if entry.doc: if entry.doc:
...@@ -894,6 +913,17 @@ class CCodeWriter(object): ...@@ -894,6 +913,17 @@ class CCodeWriter(object):
def lookup_filename(self, filename): def lookup_filename(self, filename):
return self.globalstate.lookup_filename(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: class PyrexCodeWriter:
# f file output file # f file output file
......
...@@ -906,7 +906,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -906,7 +906,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if entry.name == "__weakref__": if entry.name == "__weakref__":
code.putln("p->%s = 0;" % entry.cname) code.putln("p->%s = 0;" % entry.cname)
else: 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__") entry = scope.lookup_here("__new__")
if entry and entry.is_special: if entry and entry.is_special:
if entry.trivial_signature: if entry.trivial_signature:
...@@ -916,7 +916,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -916,7 +916,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"if (%s(%s) < 0) {" % "if (%s(%s) < 0) {" %
(entry.func_cname, cinit_args)) (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(
"}") "}")
code.putln( code.putln(
...@@ -945,7 +945,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -945,7 +945,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if weakref_slot in scope.var_entries: if weakref_slot in scope.var_entries:
code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
for entry in py_attrs: 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: if base_type:
tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
if tp_dealloc is None: if tp_dealloc is None:
...@@ -1054,7 +1054,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1054,7 +1054,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for entry in py_attrs: for entry in py_attrs:
name = "p->%s" % entry.cname name = "p->%s" % entry.cname
code.putln("tmp = ((PyObject*)%s);" % name) 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("Py_XDECREF(tmp);")
code.putln( code.putln(
"return 0;") "return 0;")
...@@ -1591,7 +1591,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1591,7 +1591,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("PyObject* %s;" % Naming.retval_cname) code.putln("PyObject* %s;" % Naming.retval_cname)
tempdecl_code = code.insertion_point() 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))); 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): ...@@ -1646,11 +1646,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.use_utility_code(Nodes.traceback_utility_code) env.use_utility_code(Nodes.traceback_utility_code)
code.putln("%s = NULL;" % Naming.retval_cname) code.putln("%s = NULL;" % Naming.retval_cname)
code.put_label(code.return_label) code.put_label(code.return_label)
code.putln('if (__Pyx_FinishRefcountContext() == -1) {') code.put_finish_refcount_context(self.pos, env.qualified_name,
code.putln(code.set_error_info(self.pos)) "NULL", Naming.retval_cname)
code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name)
code.putln('%s = NULL;' % Naming.retval_cname)
code.putln('}')
code.putln("#if PY_MAJOR_VERSION < 3") code.putln("#if PY_MAJOR_VERSION < 3")
code.putln("return;") code.putln("return;")
code.putln("#else") code.putln("#else")
......
...@@ -1023,7 +1023,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1023,7 +1023,7 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Automatic lead-ins for certain special functions # ----- Automatic lead-ins for certain special functions
if is_getbuffer_slot: if is_getbuffer_slot:
self.getbuffer_init(code) self.getbuffer_init(code)
code.putln('__Pyx_SetupRefcountContext("%s");' % self.entry.name) code.put_setup_refcount_context(self.entry.name)
# ----- Fetch arguments # ----- Fetch arguments
self.generate_argument_parsing_code(env, code) self.generate_argument_parsing_code(env, code)
# If an argument is assigned to in the body, we must # If an argument is assigned to in the body, we must
...@@ -1144,14 +1144,11 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1144,14 +1144,11 @@ class FuncDefNode(StatNode, BlockNode):
err_val = default_retval err_val = default_retval
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))
if err_val is None:
code.putln('__Pyx_FinishRefcountContext();') code.put_finish_refcount_context(self.pos,
else: self.entry.qualified_name,
code.putln('if (__Pyx_FinishRefcountContext() == -1) {') Naming.retval_cname,
code.putln(code.set_error_info(self.pos)) err_val)
code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
code.putln('%s = %s;' % (Naming.retval_cname, err_val))
code.putln('}')
if not self.return_type.is_void: if not self.return_type.is_void:
code.putln("return %s;" % Naming.retval_cname) code.putln("return %s;" % Naming.retval_cname)
......
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