Commit fe60bf77 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Improvements to TempsBlockNode interface

parent 3c918b7f
......@@ -314,7 +314,7 @@ class CodeWriter(TreeVisitor):
of the temporary which that block allocates.
"""
idx = 0
for handle in node.handles:
for handle in node.temps:
self.tempnames[handle] = "$%d_%d" % (self.tempblockindex, idx)
idx += 1
self.tempblockindex += 1
......
......@@ -433,29 +433,28 @@ class WithTransform(CythonTransform):
pipeline=[NormalizeTree(None)])
def visit_WithStatNode(self, node):
excinfo_tempblock = TempsBlockNode(node.pos, [PyrexTypes.py_object_type], None)
excinfo_temp = TempHandle(PyrexTypes.py_object_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_tempblock.new_ref_node(0, node.pos)
u'EXCINFO' : excinfo_temp.ref(node.pos)
}, pos=node.pos)
# Set except excinfo target to EXCINFO
result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = (
excinfo_tempblock.new_ref_node(0, node.pos))
excinfo_temp.ref(node.pos))
else:
result = self.template_without_target.substitute({
u'EXPR' : node.manager,
u'BODY' : node.body,
u'EXCINFO' : excinfo_tempblock.new_ref_node(0, node.pos)
u'EXCINFO' : excinfo_temp.ref(node.pos)
}, pos=node.pos)
# Set except excinfo target to EXCINFO
result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = (
excinfo_tempblock.new_ref_node(0, node.pos))
excinfo_temp.ref(node.pos))
excinfo_tempblock.body = result
return excinfo_tempblock
return TempsBlockNode(node.pos, temps=[excinfo_temp], body=result)
class DecoratorTransform(CythonTransform):
......
......@@ -113,17 +113,19 @@ class TemplateTransform(VisitorTransform):
def __call__(self, node, substitutions, temps, pos):
self.substitutions = substitutions
self.pos = pos
self.temps = temps
if len(temps) > 0:
self.tempblock = UtilNodes.TempsBlockNode(self.get_pos(node),
[PyrexTypes.py_object_type for x in temps],
body=None)
self.tempblock.body = super(TemplateTransform, self).__call__(node)
return self.tempblock
else:
return super(TemplateTransform, self).__call__(node)
tempmap = {}
temphandles = []
for temp in temps:
handle = UtilNodes.TempHandle(PyrexTypes.py_object_type)
tempmap[temp] = 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)
return result
def get_pos(self, node):
if self.pos:
......@@ -150,15 +152,13 @@ class TemplateTransform(VisitorTransform):
else:
return self.visit_Node(node) # make copy as usual
def visit_NameNode(self, node):
try:
tmpidx = self.temps.index(node.name)
except:
return self.try_substitution(node, node.name)
else:
temphandle = self.tempmap.get(node.name)
if temphandle:
# Replace name with temporary
return self.tempblock.new_ref_node(tmpidx, self.get_pos(node))
return temphandle.ref(self.get_pos(node))
else:
return self.try_substitution(node, node.name)
def visit_ExprStatNode(self, node):
# If an expression-as-statement consists of only a replaceable
......
......@@ -14,6 +14,9 @@ class TempHandle(object):
def __init__(self, type):
self.type = type
def ref(self, pos):
return TempRefNode(pos, handle=self, type=self.type)
class TempRefNode(ExprNode):
# handle TempHandle
subexprs = []
......@@ -52,29 +55,17 @@ class TempsBlockNode(Node):
The variables can be referred to using a TempRefNode
(which can be constructed by calling get_ref_node).
"""
child_attrs = ["body"]
def __init__(self, pos, types, body):
self.handles = [TempHandle(t) for t in types]
Node.__init__(self, pos, body=body)
def new_ref_node(self, index, pos):
handle = self.handles[index]
return TempRefNode(pos, handle=handle, type=handle.type)
def append_temp(self, type, pos):
"""
Appends a new temporary which this block manages, and returns
its index.
"""
self.handle.append(TempHandle(type))
return len(self.handle) - 1
# temps [TempHandle]
# body StatNode
child_attrs = ["body"]
def generate_execution_code(self, code):
for handle in self.handles:
for handle in self.temps:
handle.temp = code.funcstate.allocate_temp(handle.type)
self.body.generate_execution_code(code)
for handle in self.handles:
for handle in self.temps:
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