From: Dag Sverre Seljebotn Date: Fri, 15 Aug 2008 18:00:02 +0000 (+0200) Subject: Cloneable buffer IndexNode (preparations for buffer inplace operators) X-Git-Tag: 0.9.8.1~35 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c462cf06d410ac0c997eca30be6f759cd2c6a26b;p=cython.git Cloneable buffer IndexNode (preparations for buffer inplace operators) --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index a1b7982e..b7e2b406 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1369,6 +1369,10 @@ class IndexNode(ExprNode): # Note: This might be cleaned up by having IndexNode # parsed in a saner way and only construct the tuple if # needed. + + # Note that this function must leave IndexNode in a cloneable state. + # For buffers, self.index is packed out on the initial analysis, and + # when cloning self.indices is copied. self.is_buffer_access = False self.base.analyse_types(env) @@ -1379,11 +1383,16 @@ class IndexNode(ExprNode): skip_child_analysis = False buffer_access = False if self.base.type.is_buffer: - assert isinstance(self.base, NameNode) - if isinstance(self.index, TupleNode): - indices = self.index.args + assert hasattr(self.base, "entry") # Must be a NameNode-like node + if self.indices: + indices = self.indices else: - indices = [self.index] + # On cloning, indices is cloned. Otherwise, unpack index into indices + assert not isinstance(self.index, CloneNode) + if isinstance(self.index, TupleNode): + indices = self.index.args + else: + indices = [self.index] if len(indices) == self.base.type.ndim: buffer_access = True skip_child_analysis = True @@ -1469,7 +1478,7 @@ class IndexNode(ExprNode): def generate_subexpr_evaluation_code(self, code): self.base.generate_evaluation_code(code) - if self.index is not None: + if not self.indices: self.index.generate_evaluation_code(code) else: for i in self.indices: @@ -1477,7 +1486,7 @@ class IndexNode(ExprNode): def generate_subexpr_disposal_code(self, code): self.base.generate_disposal_code(code) - if self.index is not None: + if not self.indices: self.index.generate_disposal_code(code) else: for i in self.indices: diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index f10d278d..246b7e5d 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -2555,11 +2555,29 @@ class InPlaceAssignmentNode(AssignmentNode): self.dup = self.lhs self.dup.analyse_types(env) if isinstance(self.lhs, ExprNodes.NameNode): - target_lhs = ExprNodes.NameNode(self.dup.pos, name = self.dup.name, is_temp = self.dup.is_temp, entry = self.dup.entry) + target_lhs = ExprNodes.NameNode(self.dup.pos, + name = self.dup.name, + is_temp = self.dup.is_temp, + entry = self.dup.entry) elif isinstance(self.lhs, ExprNodes.AttributeNode): - target_lhs = ExprNodes.AttributeNode(self.dup.pos, obj = ExprNodes.CloneNode(self.lhs.obj), attribute = self.dup.attribute, is_temp = self.dup.is_temp) + target_lhs = ExprNodes.AttributeNode(self.dup.pos, + obj = ExprNodes.CloneNode(self.lhs.obj), + attribute = self.dup.attribute, + is_temp = self.dup.is_temp) elif isinstance(self.lhs, ExprNodes.IndexNode): - target_lhs = ExprNodes.IndexNode(self.dup.pos, base = ExprNodes.CloneNode(self.dup.base), index = ExprNodes.CloneNode(self.lhs.index), is_temp = self.dup.is_temp) + if self.lhs.index: + index = ExprNodes.CloneNode(self.lhs.index) + else: + index = None + if self.lhs.indices: + indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices] + else: + indices = [] + target_lhs = ExprNodes.IndexNode(self.dup.pos, + base = ExprNodes.CloneNode(self.dup.base), + index = index, + indices = indices, + is_temp = self.dup.is_temp) self.lhs = target_lhs return self.dup