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
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):
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:
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
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 = []
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):