Commit 0b414387 authored by Vitja Makarov's avatar Vitja Makarov

Fix external reference assignment

parent d0627fcb
......@@ -1738,6 +1738,12 @@ class CCodeWriter(object):
self.putln("%s_%sDECREF(%s);" % (
prefix, X, self.as_pyobject(cname, type)))
def put_decref_set(self, cname, rhs_cname):
self.putln("__Pyx_DECREF_SET(%s, %s);" % (cname, rhs_cname))
def put_xdecref_set(self, cname, rhs_cname):
self.putln("__Pyx_XDECREF_SET(%s, %s);" % (cname, rhs_cname))
def put_var_decref(self, entry):
if entry.type.is_pyobject:
self.putln("__Pyx_XDECREF(%s);" % self.entry_as_pyobject(entry))
......
......@@ -1895,7 +1895,7 @@ class NameNode(AtomicExprNode):
# variables that the acquired buffer info is stored to is allocated
# per entry and coupled with it.
self.generate_acquire_buffer(rhs, code)
assigned = False
if self.type.is_pyobject:
#print "NameNode.generate_assignment_code: to", self.name ###
#print "...from", rhs ###
......@@ -1910,18 +1910,26 @@ class NameNode(AtomicExprNode):
code.put_xgotref(self.py_result())
else:
code.put_gotref(self.py_result())
assigned = True
if entry.is_cglobal:
code.put_decref(self.result(), self.ctype())
code.put_decref_set(
self.result(), rhs.result_as(self.ctype()))
else:
if not self.cf_is_null:
if self.cf_maybe_null:
code.put_xdecref(self.result(), self.ctype())
code.put_xdecref_set(
self.result(), rhs.result_as(self.ctype()))
else:
code.put_decref(self.result(), self.ctype())
code.put_decref_set(
self.result(), rhs.result_as(self.ctype()))
else:
assigned = False
if is_external_ref:
code.put_giveref(rhs.py_result())
if not self.type.is_memoryviewslice:
code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
if not assigned:
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)
......
......@@ -531,6 +531,15 @@ static int __Pyx_check_binary_version(void) {
#define __Pyx_XGIVEREF(r)
#endif /* CYTHON_REFNANNY */
#define __Pyx_XDECREF_SET(r, v) do { \
PyObject *tmp = (PyObject *) r; \
r = v; __Pyx_XDECREF(tmp); \
} while (0)
#define __Pyx_DECREF_SET(r, v) do { \
PyObject *tmp = (PyObject *) r; \
r = v; __Pyx_DECREF(tmp); \
} while (0)
#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
......
# Test that variable visible outside of the local scope (e.g. closure, cglobals)
# is set before original value is decrefed.
cdef object g
def test_cglobals_reassignment():
"""
>>> test_cglobals_reassignment()
1234
"""
global g
class Special:
def __del__(self):
print g
g = (Special(),)
g = 1234
def test_closure_reassignment():
"""
>>> test_closure_reassignment()
4321
"""
class Special:
def __del__(self):
print c
c = (Special(),)
c = 4321
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