Backed out changeset c59d0e5d0bdf -- it broke C array inplace operations
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 16:11:40 +0000 (18:11 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 15 Aug 2008 16:11:40 +0000 (18:11 +0200)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
tests/run/bufaccess.pyx

index 9ec23bcdba4a4c32508548c4d5e9570e80fc72a9..a1b7982e416dcd840ae3f24867cace5a2123ca63 100644 (file)
@@ -1379,7 +1379,7 @@ class IndexNode(ExprNode):
         skip_child_analysis = False
         buffer_access = False
         if self.base.type.is_buffer:
-            assert hasattr(self.base, "entry") # Must be a NameNode-like node
+            assert isinstance(self.base, NameNode)
             if isinstance(self.index, TupleNode):
                 indices = self.index.args
             else:
@@ -1394,7 +1394,7 @@ class IndexNode(ExprNode):
 
         if buffer_access:
             self.indices = indices
-            self.index = None # note that original is kept in _index, which is used for cloning
+            self.index = None
             self.type = self.base.type.dtype
             self.is_buffer_access = True
             self.buffer_type = self.base.entry.type
@@ -1469,19 +1469,19 @@ class IndexNode(ExprNode):
 
     def generate_subexpr_evaluation_code(self, code):
         self.base.generate_evaluation_code(code)
-        if self.indices:
+        if self.index is not None:
+            self.index.generate_evaluation_code(code)
+        else:
             for i in self.indices:
                 i.generate_evaluation_code(code)
-        else:
-            self.index.generate_evaluation_code(code)       
-
+        
     def generate_subexpr_disposal_code(self, code):
         self.base.generate_disposal_code(code)
-        if self.indices:
+        if self.index is not None:
+            self.index.generate_disposal_code(code)
+        else:
             for i in self.indices:
                 i.generate_disposal_code(code)
-        else:
-            self.index.generate_disposal_code(code)
 
     def generate_result_code(self, code):
         if self.is_buffer_access:
@@ -1525,34 +1525,30 @@ class IndexNode(ExprNode):
                 value_code,
                 self.index_unsigned_parameter(),
                 code.error_goto(self.pos)))
-
-    def generate_buffer_assignment_code(self, rhs, code, op=""):
-        # Used from generate_assignment_code and InPlaceAssignmentNode
-        ptrexpr = self.buffer_lookup_code(code)
-        if self.buffer_type.dtype.is_pyobject:
-            # Must manage refcounts. Decref what is already there
-            # and incref what we put in.
-            ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type)
-            if rhs.is_temp: #TODO: REMOVE
-                rhs_code = code.funcstate.allocate_temp(rhs.type)
-            else:
-                rhs_code = rhs.result_code
-            code.putln("%s = %s;" % (ptr, ptrexpr))
-            code.putln("Py_DECREF(*%s); Py_INCREF(%s);" % (
-                ptr, rhs_code
-                ))
-            code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
-            if rhs.is_temp:
-                code.funcstate.release_temp(rhs_code)
-            code.funcstate.release_temp(ptr)
-        else: 
-            # Simple case
-            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result_code))
-
+    
     def generate_assignment_code(self, rhs, code):
         self.generate_subexpr_evaluation_code(code)
         if self.is_buffer_access:
-            self.generate_buffer_assignment_code(rhs, code)
+            ptrexpr = self.buffer_lookup_code(code)
+            if self.buffer_type.dtype.is_pyobject:
+                # Must manage refcounts. Decref what is already there
+                # and incref what we put in.
+                ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type)
+                if rhs.is_temp:
+                    rhs_code = code.funcstate.allocate_temp(rhs.type)
+                else:
+                    rhs_code = rhs.result_code
+                code.putln("%s = %s;" % (ptr, ptrexpr))
+                code.putln("Py_DECREF(*%s); Py_INCREF(%s);" % (
+                    ptr, rhs_code
+                    ))
+                code.putln("*%s = %s;" % (ptr, rhs_code))
+                if rhs.is_temp:
+                    code.funcstate.release_temp(rhs_code)
+                code.funcstate.release_temp(ptr)
+            else: 
+                # Simple case
+                code.putln("*%s = %s;" % (ptrexpr, rhs.result_code))
         elif self.type.is_pyobject:
             self.generate_setitem_code(rhs.py_result(), code)
         else:
@@ -3941,7 +3937,6 @@ class CoercionNode(ExprNode):
     def __init__(self, arg):
         self.pos = arg.pos
         self.arg = arg
-        self.options = arg.options
         if debug_coercion:
             print("%s Coercing %s" % (self, self.arg))
             
index df2ac65ec76ad8140aca9940d2b21d3c9893ee5f..f10d278dd61ba034367e8b4380d1068e7c720f75 100644 (file)
@@ -71,12 +71,10 @@ class Node(object):
     #  pos         (string, int, int)   Source file position
     #  is_name     boolean              Is a NameNode
     #  is_literal  boolean              Is a ConstNode
-    #  options     dict                 Compiler directives for this node
     
     is_name = 0
     is_literal = 0
     temps = None
-    options = {}
 
     # All descandants should set child_attrs to a list of the attributes
     # containing nodes considered "children" in the tree. Each such attribute
@@ -2519,13 +2517,12 @@ class InPlaceAssignmentNode(AssignmentNode):
     def generate_execution_code(self, code):
         self.rhs.generate_evaluation_code(code)
         self.dup.generate_subexpr_evaluation_code(code)
-        # self.dup.generate_result_code is run only if it is not buffer access
+        self.dup.generate_result_code(code)
         if self.operator == "**":
             extra = ", Py_None"
         else:
             extra = ""
         if self.lhs.type.is_pyobject:
-            self.dup.generate_result_code(code)
             code.putln(
                 "%s = %s(%s, %s%s); %s" % (
                     self.result.result_code, 
@@ -2548,12 +2545,7 @@ class InPlaceAssignmentNode(AssignmentNode):
                 else:
                     error(self.pos, "No C inplace power operator")
             # have to do assignment directly to avoid side-effects
-            import ExprNodes
-            if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
-                self.lhs.generate_buffer_assignment_code(self.rhs, code, c_op)
-            else:
-                self.dup.generate_result_code(code)
-                code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
+            code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
             self.rhs.generate_disposal_code(code)
         if self.dup.is_temp:
             self.dup.generate_subexpr_disposal_code(code)
@@ -2563,23 +2555,11 @@ 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,
-                                            options = self.dup.options)
+            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,
-                                                 options = self.dup.options)
+            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,
-                                                 options = self.dup.options)
+            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)
         self.lhs = target_lhs
         return self.dup
     
index 5d7d32e19f95b4d252027a6a679dcd0a7285953c..a4ad192cf72ad83e22c3eb42300ba73ed7d8e921 100644 (file)
@@ -596,23 +596,12 @@ TODO
     uc[0] = <int>3.14
     print uc[0]
 
-    cdef char* ch = "asfd"
-    cdef object[object] objbuf
-    objbuf[3] = ch
-
 
 #
 # Testing that accessing data using various types of buffer access
 # all works.
 #
 
-def printbuf_int(object[int] buf, shape):
-    # Utility func
-    cdef int i
-    for i in range(shape[0]):
-        print buf[i],
-    print 'END'
-
 
 @testcase
 def printbuf_int_2d(o, shape):
@@ -665,24 +654,6 @@ def printbuf_float(o, shape):
     print "END"
 
 
-#
-# Test assignments
-#
-@testcase
-def inplace_operators(object[int] buf):
-    """
-    >>> buf = IntMockBuffer(None, [2, 2])
-    >>> inplace_operators(buf)
-    >>> printbuf_int(buf, (2,))
-    0 3 END
-    """
-    cdef int j = 0
-    buf[1] += 1
-    buf[j] *= 2
-    buf[0] -= 4
-
-
-
 #
 # Typedefs
 #