Commit de6dcfae authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Backed out changeset c59d0e5d0bdf -- it broke C array inplace operations

parent fed7b531
...@@ -1379,7 +1379,7 @@ class IndexNode(ExprNode): ...@@ -1379,7 +1379,7 @@ class IndexNode(ExprNode):
skip_child_analysis = False skip_child_analysis = False
buffer_access = False buffer_access = False
if self.base.type.is_buffer: 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): if isinstance(self.index, TupleNode):
indices = self.index.args indices = self.index.args
else: else:
...@@ -1394,7 +1394,7 @@ class IndexNode(ExprNode): ...@@ -1394,7 +1394,7 @@ class IndexNode(ExprNode):
if buffer_access: if buffer_access:
self.indices = indices 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.type = self.base.type.dtype
self.is_buffer_access = True self.is_buffer_access = True
self.buffer_type = self.base.entry.type self.buffer_type = self.base.entry.type
...@@ -1469,19 +1469,19 @@ class IndexNode(ExprNode): ...@@ -1469,19 +1469,19 @@ class IndexNode(ExprNode):
def generate_subexpr_evaluation_code(self, code): def generate_subexpr_evaluation_code(self, code):
self.base.generate_evaluation_code(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: for i in self.indices:
i.generate_evaluation_code(code) i.generate_evaluation_code(code)
else:
self.index.generate_evaluation_code(code)
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
self.base.generate_disposal_code(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: for i in self.indices:
i.generate_disposal_code(code) i.generate_disposal_code(code)
else:
self.index.generate_disposal_code(code)
def generate_result_code(self, code): def generate_result_code(self, code):
if self.is_buffer_access: if self.is_buffer_access:
...@@ -1525,34 +1525,30 @@ class IndexNode(ExprNode): ...@@ -1525,34 +1525,30 @@ class IndexNode(ExprNode):
value_code, value_code,
self.index_unsigned_parameter(), self.index_unsigned_parameter(),
code.error_goto(self.pos))) 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): def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
if self.is_buffer_access: 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: elif self.type.is_pyobject:
self.generate_setitem_code(rhs.py_result(), code) self.generate_setitem_code(rhs.py_result(), code)
else: else:
...@@ -3941,7 +3937,6 @@ class CoercionNode(ExprNode): ...@@ -3941,7 +3937,6 @@ class CoercionNode(ExprNode):
def __init__(self, arg): def __init__(self, arg):
self.pos = arg.pos self.pos = arg.pos
self.arg = arg self.arg = arg
self.options = arg.options
if debug_coercion: if debug_coercion:
print("%s Coercing %s" % (self, self.arg)) print("%s Coercing %s" % (self, self.arg))
......
...@@ -71,12 +71,10 @@ class Node(object): ...@@ -71,12 +71,10 @@ class Node(object):
# pos (string, int, int) Source file position # pos (string, int, int) Source file position
# is_name boolean Is a NameNode # is_name boolean Is a NameNode
# is_literal boolean Is a ConstNode # is_literal boolean Is a ConstNode
# options dict Compiler directives for this node
is_name = 0 is_name = 0
is_literal = 0 is_literal = 0
temps = None temps = None
options = {}
# All descandants should set child_attrs to a list of the attributes # All descandants should set child_attrs to a list of the attributes
# containing nodes considered "children" in the tree. Each such attribute # containing nodes considered "children" in the tree. Each such attribute
...@@ -2519,13 +2517,12 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -2519,13 +2517,12 @@ class InPlaceAssignmentNode(AssignmentNode):
def generate_execution_code(self, code): def generate_execution_code(self, code):
self.rhs.generate_evaluation_code(code) self.rhs.generate_evaluation_code(code)
self.dup.generate_subexpr_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 == "**": if self.operator == "**":
extra = ", Py_None" extra = ", Py_None"
else: else:
extra = "" extra = ""
if self.lhs.type.is_pyobject: if self.lhs.type.is_pyobject:
self.dup.generate_result_code(code)
code.putln( code.putln(
"%s = %s(%s, %s%s); %s" % ( "%s = %s(%s, %s%s); %s" % (
self.result.result_code, self.result.result_code,
...@@ -2548,12 +2545,7 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -2548,12 +2545,7 @@ class InPlaceAssignmentNode(AssignmentNode):
else: else:
error(self.pos, "No C inplace power operator") error(self.pos, "No C inplace power operator")
# have to do assignment directly to avoid side-effects # have to do assignment directly to avoid side-effects
import ExprNodes code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
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) )
self.rhs.generate_disposal_code(code) self.rhs.generate_disposal_code(code)
if self.dup.is_temp: if self.dup.is_temp:
self.dup.generate_subexpr_disposal_code(code) self.dup.generate_subexpr_disposal_code(code)
...@@ -2563,23 +2555,11 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -2563,23 +2555,11 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup = self.lhs self.dup = self.lhs
self.dup.analyse_types(env) self.dup.analyse_types(env)
if isinstance(self.lhs, ExprNodes.NameNode): if isinstance(self.lhs, ExprNodes.NameNode):
target_lhs = ExprNodes.NameNode(self.dup.pos, target_lhs = ExprNodes.NameNode(self.dup.pos, name = self.dup.name, is_temp = self.dup.is_temp, entry = self.dup.entry)
name = self.dup.name,
is_temp = self.dup.is_temp,
entry = self.dup.entry,
options = self.dup.options)
elif isinstance(self.lhs, ExprNodes.AttributeNode): elif isinstance(self.lhs, ExprNodes.AttributeNode):
target_lhs = ExprNodes.AttributeNode(self.dup.pos, target_lhs = ExprNodes.AttributeNode(self.dup.pos, obj = ExprNodes.CloneNode(self.lhs.obj), attribute = self.dup.attribute, is_temp = self.dup.is_temp)
obj = ExprNodes.CloneNode(self.lhs.obj),
attribute = self.dup.attribute,
is_temp = self.dup.is_temp,
options = self.dup.options)
elif isinstance(self.lhs, ExprNodes.IndexNode): elif isinstance(self.lhs, ExprNodes.IndexNode):
target_lhs = ExprNodes.IndexNode(self.dup.pos, 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)
base = ExprNodes.CloneNode(self.dup.base),
index = ExprNodes.CloneNode(self.lhs._index),
is_temp = self.dup.is_temp,
options = self.dup.options)
self.lhs = target_lhs self.lhs = target_lhs
return self.dup return self.dup
......
...@@ -596,23 +596,12 @@ TODO ...@@ -596,23 +596,12 @@ TODO
uc[0] = <int>3.14 uc[0] = <int>3.14
print uc[0] print uc[0]
cdef char* ch = "asfd"
cdef object[object] objbuf
objbuf[3] = ch
# #
# Testing that accessing data using various types of buffer access # Testing that accessing data using various types of buffer access
# all works. # 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 @testcase
def printbuf_int_2d(o, shape): def printbuf_int_2d(o, shape):
...@@ -665,24 +654,6 @@ def printbuf_float(o, shape): ...@@ -665,24 +654,6 @@ def printbuf_float(o, shape):
print "END" 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 # Typedefs
# #
......
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