Commit cad41704 authored by Robert Bradshaw's avatar Robert Bradshaw

Fix two more closure bugs.

parent 92135ccf
......@@ -70,7 +70,7 @@ class ControlFlow(object):
if current is None:
return (None, None)
state = current._get_pos_state_local(item, pos)
while state is None and current.incoming is not None:
while (state is None or state == (None, None)) and current.incoming is not None:
current = current.incoming
state = current._get_pos_state_local(item, pos)
if state is None:
......
......@@ -1220,8 +1220,6 @@ class FuncDefNode(StatNode, BlockNode):
if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
entry.xdecref_cleanup = 1
if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
for entry in lenv.var_entries:
if entry.used and not entry.in_closure:
code.put_var_decref(entry)
......@@ -1234,6 +1232,8 @@ class FuncDefNode(StatNode, BlockNode):
code.put_var_giveref(entry)
elif not entry.in_closure and src != 'arg':
code.put_var_decref(entry)
if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
# ----- Return
# This code is duplicated in ModuleNode.generate_module_init_func
......@@ -1861,10 +1861,11 @@ class DefNode(FuncDefNode):
for arg in self.args:
if not arg.name:
error(arg.pos, "Missing argument name")
if arg.needs_conversion:
arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
else:
env.control_flow.set_state((), (arg.name, 'source'), 'arg')
env.control_flow.set_state((), (arg.name, 'initalized'), True)
if arg.needs_conversion:
arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
if arg.type.is_pyobject:
arg.entry.init = "0"
arg.entry.init_to_none = 0
......
......@@ -50,6 +50,15 @@ True
>>> inner_funcs[0](16), inner_funcs[1](32), inner_funcs[2](64)
(19, 37, 73)
>>> switch_funcs([1,2,3], [4,5,6], 0)([10])
[1, 2, 3, 10]
>>> switch_funcs([1,2,3], [4,5,6], 1)([10])
[4, 5, 6, 10]
>>> switch_funcs([1,2,3], [4,5,6], 2) is None
True
>>> call_ignore_func()
"""
def add_n(int n):
......@@ -125,6 +134,25 @@ def cy_twofuncs(x):
return x + b
return f
def switch_funcs(a, b, int ix):
def f(x):
return a + x
def g(x):
return b + x
if ix == 0:
return f
elif ix == 1:
return g
else:
return None
def ignore_func(x):
def f():
return x
return None
def call_ignore_func():
ignore_func((1,2,3))
def more_inner_funcs(x):
# called with x==1
......
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