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

merge

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