This time hopefully without breaking other inplace operators.
value_code,
self.index_unsigned_parameter(),
code.error_goto(self.pos)))
-
+
+ def generate_buffer_setitem_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:
+ 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:
- 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))
+ self.generate_buffer_setitem_code(rhs, code)
elif self.type.is_pyobject:
self.generate_setitem_code(rhs.py_result(), code)
else:
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))
# pos (string, int, int) Source file position
# is_name boolean Is a NameNode
# is_literal boolean Is a ConstNode
+ # options dict Compiler directives in effect for this node
is_name = 0
is_literal = 0
temps = None
+ options = None
# All descandants should set child_attrs to a list of the attributes
# containing nodes considered "children" in the tree. Each such attribute
def generate_execution_code(self, code):
self.rhs.generate_evaluation_code(code)
self.dup.generate_subexpr_evaluation_code(code)
- self.dup.generate_result_code(code)
+ # self.dup.generate_result_code is run only if it is not buffer access
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,
else:
error(self.pos, "No C inplace power operator")
# have to do assignment directly to avoid side-effects
- code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
+ import ExprNodes
+ if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
+ self.lhs.generate_buffer_setitem_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)
if self.dup.is_temp:
self.dup.generate_subexpr_disposal_code(code)
target_lhs = ExprNodes.NameNode(self.dup.pos,
name = self.dup.name,
is_temp = self.dup.is_temp,
- entry = self.dup.entry)
+ entry = self.dup.entry,
+ options = self.dup.options)
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)
+ is_temp = self.dup.is_temp,
+ options = self.dup.options)
elif isinstance(self.lhs, ExprNodes.IndexNode):
if self.lhs.index:
index = ExprNodes.CloneNode(self.lhs.index)
base = ExprNodes.CloneNode(self.dup.base),
index = index,
indices = indices,
- is_temp = self.dup.is_temp)
+ is_temp = self.dup.is_temp,
+ options = self.dup.options)
self.lhs = target_lhs
return self.dup
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):
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
#