From fe60bf77ad78d8e21467395797cc1902c525e3cb Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Thu, 25 Sep 2008 23:33:10 +0200 Subject: [PATCH] Improvements to TempsBlockNode interface --- Cython/CodeWriter.py | 2 +- Cython/Compiler/ParseTreeTransforms.py | 13 +++++----- Cython/Compiler/TreeFragment.py | 36 +++++++++++++------------- Cython/Compiler/UtilNodes.py | 27 +++++++------------ 4 files changed, 34 insertions(+), 44 deletions(-) diff --git a/Cython/CodeWriter.py b/Cython/CodeWriter.py index cbe91aab..7bfea536 100644 --- a/Cython/CodeWriter.py +++ b/Cython/CodeWriter.py @@ -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 diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index ffd136de..4d05361f 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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): diff --git a/Cython/Compiler/TreeFragment.py b/Cython/Compiler/TreeFragment.py index fcbc81e0..d1b1d574 100644 --- a/Cython/Compiler/TreeFragment.py +++ b/Cython/Compiler/TreeFragment.py @@ -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 diff --git a/Cython/Compiler/UtilNodes.py b/Cython/Compiler/UtilNodes.py index 9a217ea7..7a624fb5 100644 --- a/Cython/Compiler/UtilNodes.py +++ b/Cython/Compiler/UtilNodes.py @@ -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): -- 2.26.2