Commit 3d2a0179 authored by Stefan Behnel's avatar Stefan Behnel

merge

parents 4c06e46c ab847bb5
......@@ -320,7 +320,7 @@ class GlobalState(object):
def should_declare(self, cname, entry):
if cname in self.declared_cnames:
other = self.declared_cnames[cname]
assert entry.type == other.type
assert str(entry.type) == str(other.type)
assert entry.init == other.init
return False
else:
......@@ -749,6 +749,9 @@ class CCodeWriter(object):
def put_xgiveref(self, cname):
self.putln("__Pyx_XGIVEREF(%s);" % cname)
def put_xgotref(self, cname):
self.putln("__Pyx_XGOTREF(%s);" % cname)
def put_incref(self, cname, type, nanny=True):
if nanny:
self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type))
......
......@@ -1333,6 +1333,8 @@ class NameNode(AtomicExprNode):
#print "...from", rhs ###
#print "...LHS type", self.type, "ctype", self.ctype() ###
#print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
if entry.is_cglobal:
code.put_gotref(self.py_result())
if not self.lhs_of_first_assignment:
if entry.is_local and not Options.init_local_none:
initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
......@@ -1342,6 +1344,8 @@ class NameNode(AtomicExprNode):
code.put_xdecref(self.result(), self.ctype())
else:
code.put_decref(self.result(), self.ctype())
if entry.is_cglobal:
code.put_giveref(rhs.py_result())
code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
if debug_disposal_code:
print("NameNode.generate_assignment_code:")
......@@ -2882,6 +2886,7 @@ class AttributeNode(NewTempExprNode):
select_code = self.result()
if self.type.is_pyobject:
rhs.make_owned_reference(code)
code.put_giveref(rhs.py_result())
code.put_decref(select_code, self.ctype())
code.putln(
"%s = %s;" % (
......
......@@ -114,7 +114,7 @@ class Context:
_specific_post_parse,
InterpretCompilerDirectives(self, self.pragma_overrides),
_align_function_definitions,
FlattenInListTransform(),
# FlattenInListTransform(),
WithTransform(self),
DecoratorTransform(self),
AnalyseDeclarationsTransform(self),
......
......@@ -1640,8 +1640,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.use_utility_code(Nodes.traceback_utility_code)
code.putln("%s = NULL;" % Naming.retval_cname)
code.put_label(code.return_label)
code.put_finish_refcount_context(self.pos, env.qualified_name,
Naming.retval_cname, "NULL")
# Disabled because of confusion with refcount of global variables -- run ass2cglobal testcase to see
#code.put_finish_refcount_context(self.pos, env.qualified_name,
# Naming.retval_cname, "NULL")
code.putln("#if CYTHON_REFNANNY")
code.putln("if (__pyx_refchk) {};")
code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION < 3")
code.putln("return;")
code.putln("#else")
......@@ -2344,4 +2348,5 @@ int __Pyx_Refnanny_FinishContext(void*);
#define __Pyx_FinishRefcountContext() 0
#endif /* CYTHON_REFNANNY */
#define __Pyx_XGIVEREF(r) (r ? __Pyx_GIVEREF(r) : 0)
#define __Pyx_XGOTREF(r) (r ? __Pyx_GOTREF(r) : 0)
""")
......@@ -1068,10 +1068,10 @@ class FuncDefNode(StatNode, BlockNode):
if acquire_gil:
code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
# ----- Automatic lead-ins for certain special functions
if is_getbuffer_slot:
self.getbuffer_init(code)
if not lenv.nogil:
code.put_setup_refcount_context(self.entry.name)
if is_getbuffer_slot:
self.getbuffer_init(code)
# ----- Fetch arguments
self.generate_argument_parsing_code(env, code)
# If an argument is assigned to in the body, we must
......@@ -2145,6 +2145,7 @@ class DefNode(FuncDefNode):
self.starstar_arg.entry.cname,
self.starstar_arg.entry.cname,
self.error_value()))
code.put_gotref(self.starstar_arg.entry.cname)
if self.star_arg:
self.star_arg.entry.xdecref_cleanup = 0
code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
......@@ -2153,6 +2154,7 @@ class DefNode(FuncDefNode):
code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
self.star_arg.entry.cname, Naming.args_cname,
max_positional_args, Naming.args_cname))
code.put_gotref(self.star_arg.entry.cname)
if self.starstar_arg:
code.putln("")
code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
......@@ -4026,6 +4028,8 @@ class TryExceptStatNode(StatNode):
', '.join(['*%s' % var for var in Naming.exc_save_vars]))
code.putln("__Pyx_ExceptionSave(%s);" %
', '.join(['&%s' % var for var in Naming.exc_save_vars]))
for var in Naming.exc_save_vars:
code.put_xgotref(var)
code.putln(
"/*try:*/ {")
code.return_label = try_return_label
......@@ -4066,12 +4070,14 @@ class TryExceptStatNode(StatNode):
if code.label_used(except_return_label):
code.put_label(except_return_label)
for var in Naming.exc_save_vars: code.put_xgiveref(var)
code.putln("__Pyx_ExceptionReset(%s);" %
', '.join(Naming.exc_save_vars))
code.put_goto(old_return_label)
if code.label_used(except_end_label):
code.put_label(except_end_label)
for var in Naming.exc_save_vars: code.put_xgiveref(var)
code.putln("__Pyx_ExceptionReset(%s);" %
', '.join(Naming.exc_save_vars))
code.put_label(try_end_label)
......@@ -4170,6 +4176,8 @@ class ExceptClauseNode(Node):
exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
code.error_goto(self.pos)))
for x in self.exc_vars:
code.put_gotref(x)
if self.target:
self.exc_value.generate_evaluation_code(code)
self.target.generate_assignment_code(self.exc_value, code)
......
......@@ -3,7 +3,7 @@ from Cython.Compiler.ModuleNode import ModuleNode
from Cython.Compiler.Nodes import *
from Cython.Compiler.ExprNodes import *
from Cython.Compiler.UtilNodes import *
from Cython.Compiler.TreeFragment import TreeFragment
from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform
from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler.Errors import CompileError
try:
......@@ -539,35 +539,39 @@ class WithTransform(CythonTransform, SkipDeclarations):
finally:
if EXC:
EXIT(None, None, None)
MGR = EXIT = VALUE = EXC = None
""", temps=[u'MGR', u'EXC', u"EXIT", u"VALUE"],
pipeline=[NormalizeTree(None)])
def visit_WithStatNode(self, node):
# TODO: Cleanup badly needed
TemplateTransform.temp_name_counter += 1
handle = "__tmpvar_%d" % TemplateTransform.temp_name_counter
self.visitchildren(node, ['body'])
# FIXME: excinfo_temp should be more local to the except
# clause that uses it, to avoid the presetting to None
excinfo_temp = TempHandle(Builtin.tuple_type)
excinfo_temp = NameNode(node.pos, name=handle)#TempHandle(Builtin.tuple_type)
if node.target is not None:
result = self.template_with_target.substitute({
u'EXPR' : node.manager,
u'BODY' : node.body,
u'TARGET' : node.target,
u'EXCINFO' : excinfo_temp.ref(node.pos)
u'EXCINFO' : excinfo_temp
}, pos=node.pos)
else:
result = self.template_without_target.substitute({
u'EXPR' : node.manager,
u'BODY' : node.body,
u'EXCINFO' : excinfo_temp.ref(node.pos)
u'EXCINFO' : excinfo_temp
}, pos=node.pos)
# Set except excinfo target to EXCINFO
try_except = result.body.stats[-1].body.stats[-1]
try_except.except_clauses[0].excinfo_target = (
excinfo_temp.ref(node.pos))
try_except = result.stats[-1].body.stats[-1]
try_except.except_clauses[0].excinfo_target = NameNode(node.pos, name=handle)
# excinfo_temp.ref(node.pos))
result.body.stats[-1].body.stats[-1] = TempsBlockNode(
node.pos, temps=[excinfo_temp], body=try_except)
# result.stats[-1].body.stats[-1] = TempsBlockNode(
# node.pos, temps=[excinfo_temp], body=try_except)
return result
......
......@@ -85,7 +85,7 @@ class TestNormalizeTree(TransformTest):
t = self.run_pipeline([NormalizeTree(None)], u"pass")
self.assert_(len(t.stats) == 0)
class TestWithTransform(TransformTest):
class TestWithTransform:#(TransformTest): Disabled
def test_simplified(self):
t = self.run_pipeline([WithTransform(None)], u"""
......
......@@ -48,17 +48,17 @@ class TestTreeFragments(CythonTest):
self.assertEquals(v.pos, a.pos)
def test_temps(self):
import Cython.Compiler.Visitor as v
v.tmpnamectr = 0
TemplateTransform.temp_name_counter = 0
F = self.fragment(u"""
TMP
x = TMP
""")
T = F.substitute(temps=[u"TMP"])
s = T.body.stats
self.assert_(isinstance(s[0].expr, TempRefNode))
self.assert_(isinstance(s[1].rhs, TempRefNode))
self.assert_(s[0].expr.handle is s[1].rhs.handle)
s = T.stats
self.assert_(s[0].expr.name == "__tmpvar_1")
# self.assert_(isinstance(s[0].expr, TempRefNode))
# self.assert_(isinstance(s[1].rhs, TempRefNode))
# self.assert_(s[0].expr.handle is s[1].rhs.handle)
if __name__ == "__main__":
import unittest
......
......@@ -111,21 +111,25 @@ class TemplateTransform(VisitorTransform):
recursively applied to every member node.
"""
temp_name_counter = 0
def __call__(self, node, substitutions, temps, pos):
self.substitutions = substitutions
self.pos = pos
tempmap = {}
temphandles = []
for temp in temps:
handle = UtilNodes.TempHandle(PyrexTypes.py_object_type)
TemplateTransform.temp_name_counter += 1
handle = "__tmpvar_%d" % TemplateTransform.temp_name_counter
# handle = UtilNodes.TempHandle(PyrexTypes.py_object_type)
tempmap[temp] = handle
temphandles.append(handle)
# temphandles.append(handle)
self.tempmap = tempmap
result = super(TemplateTransform, self).__call__(node)
if temps:
result = UtilNodes.TempsBlockNode(self.get_pos(node),
temps=temphandles,
body=result)
# if temps:
# result = UtilNodes.TempsBlockNode(self.get_pos(node),
# temps=temphandles,
# body=result)
return result
def get_pos(self, node):
......@@ -156,8 +160,10 @@ class TemplateTransform(VisitorTransform):
def visit_NameNode(self, node):
temphandle = self.tempmap.get(node.name)
if temphandle:
node.name = temphandle
return node
# Replace name with temporary
return temphandle.ref(self.get_pos(node))
#return temphandle.ref(self.get_pos(node))
else:
return self.try_substitution(node, node.name)
......
......@@ -45,21 +45,30 @@ class RefnannyContext(object):
msg += "\n Acquired on lines: " + ", ".join(["%d" % x for x in linenos])
self.errors.append("References leaked: %s" % msg)
if self.errors:
print self.errors
# raise RefnannyException("\n".join(self.errors))
# print self.errors
raise RefnannyException("\n".join(self.errors))
cdef public void* __Pyx_Refnanny_NewContext(char* funcname, int lineno) except NULL:
if exc.PyErr_Occurred() != NULL:
print "error flag set on newcontext?"
return NULL
ctx = RefnannyContext()
Py_INCREF(ctx)
return <void*>ctx
cdef public void __Pyx_Refnanny_GOTREF(void* ctx, object obj, int lineno):
cdef exc.PyObject* type, *value, *tb
if ctx == NULL: return
exc.PyErr_Fetch(&type, &value, &tb)
(<object>ctx).regref(obj, lineno)
exc.PyErr_Restore(<object>type, <object>value, <object>tb)
cdef public void __Pyx_Refnanny_GIVEREF(void* ctx, object obj, int lineno):
cdef exc.PyObject* type, *value, *tb
if ctx == NULL: return
exc.PyErr_Fetch(&type, &value, &tb)
(<object>ctx).delref(obj, lineno)
exc.PyErr_Restore(<object>type, <object>value, <object>tb)
cdef public void __Pyx_Refnanny_INCREF(void* ctx, object obj, int lineno):
Py_INCREF(obj)
......@@ -72,17 +81,16 @@ cdef public void __Pyx_Refnanny_DECREF(void* ctx, object obj, int lineno):
Py_DECREF(obj)
cdef public int __Pyx_Refnanny_FinishContext(void* ctx) except -1:
# cdef exc.PyObject* type, *value, *tb
## if exc.PyErr_Occurred():
## exc.PyErr_Fetch(&type, &value, &tb)
## Py_XDECREF(<object>type); Py_XDECREF(<object>value); Py_XDECREF(<object>tb)
## print "cleared!"
## print (exc.PyErr_Occurred() == NULL)
cdef exc.PyObject* type, *value, *tb
if ctx == NULL:
assert False
exc.PyErr_Fetch(&type, &value, &tb)
obj = <object>ctx
try:
obj.end()
finally:
Py_DECREF(obj)
exc.PyErr_Restore(<object>type, <object>value, <object>tb)
return 0
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