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