Commit fcfaa416 authored by Stefan Behnel's avatar Stefan Behnel

clean up new-style temps after use (breaks code for now)

parent d69599e4
......@@ -137,6 +137,25 @@ class FunctionState(object):
self.temps_free[type] = freelist
freelist.append(name)
def temps_in_use(self):
"""Return a list of (cname,type) tuples of temp names and their type
that are currently in use.
"""
used = []
for name, type in self.temps_allocated:
freelist = self.temps_free.get(type)
if freelist is None or name not in freelist:
used.append((name, type))
return used
def py_temps_in_use(self):
"""Return a list of (cname,type) tuples of temp names and their type
that are currently in use. This includes only Python object types.
"""
return [(name, type)
for name, type in self.temps_in_use()
if type.is_pyobject]
class GlobalState(object):
# filename_table {string : int} for finding filename table indexes
# filename_list [string] filenames in filename table order
......
......@@ -1060,7 +1060,12 @@ class FuncDefNode(StatNode, BlockNode):
if code.error_label in code.labels_used:
code.put_goto(code.return_label)
code.put_label(code.error_label)
# cleanup temps the old way
code.put_var_xdecrefs(lenv.temp_entries)
# cleanup temps the new way
for cname, type in code.funcstate.temps_allocated:
if type.is_pyobject:
code.put_xdecref(cname, type)
# Clean up buffers -- this calls a Python function
# so need to save and restore error state
......@@ -3287,8 +3292,12 @@ class ReturnStatNode(StatNode):
"%s = %s;" % (
Naming.retval_cname,
self.return_type.default_value))
# free temps the old way
for entry in self.temps_in_use:
code.put_var_decref_clear(entry)
# free temps the new way
for cname, type in code.funcstate.py_temps_in_use():
code.put_decref_clear(cname, type)
#code.putln(
# "goto %s;" %
# code.return_label)
......
......@@ -11,12 +11,17 @@ from ExprNodes import AtomicExprNode
class TempHandle(object):
temp = None
needs_xdecref = False
def __init__(self, type):
self.type = type
self.needs_cleanup = type.is_pyobject
def ref(self, pos):
return TempRefNode(pos, handle=self, type=self.type)
def cleanup_ref(self, pos):
return CleanupTempRefNode(pos, handle=self, type=self.type)
class TempRefNode(AtomicExprNode):
# handle TempHandle
......@@ -40,10 +45,22 @@ class TempRefNode(AtomicExprNode):
def generate_assignment_code(self, rhs, code):
if self.type.is_pyobject:
rhs.make_owned_reference(code)
# TODO: analyse control flow to see if this is necessary
code.put_xdecref(self.result(), self.ctype())
code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
rhs.generate_post_assignment_code(code)
class CleanupTempRefNode(TempRefNode):
# handle TempHandle
def generate_assignment_code(self, rhs, code):
pass
def generate_execution_code(self, code):
if self.type.is_pyobject:
code.put_decref_clear(self.result(), self.type)
self.handle.needs_cleanup = False
class TempsBlockNode(Node):
"""
Creates a block which allocates temporary variables.
......@@ -65,6 +82,11 @@ class TempsBlockNode(Node):
handle.temp = code.funcstate.allocate_temp(handle.type)
self.body.generate_execution_code(code)
for handle in self.temps:
if handle.needs_cleanup:
if handle.needs_xdecref:
code.put_xdecref_clear(handle.temp, handle.type)
else:
code.put_decref_clear(handle.temp, handle.type)
code.funcstate.release_temp(handle.temp)
def analyse_control_flow(self, env):
......
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