Commit 06c0c96b authored by Mark Florisson's avatar Mark Florisson

Fix segfault caused by NULL suboffsets

parent f5134ba8
...@@ -471,7 +471,10 @@ def assign_scalar(dst, scalar, code): ...@@ -471,7 +471,10 @@ def assign_scalar(dst, scalar, code):
code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, dst.result())) code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, dst.result()))
dst_temp = "__pyx_temp_slice" dst_temp = "__pyx_temp_slice"
with slice_iter(dst.type, dst_temp, dst.type.ndim, code) as p: # with slice_iter(dst.type, dst_temp, dst.type.ndim, code) as p:
slice_iter_obj = slice_iter(dst.type, dst_temp, dst.type.ndim, code)
p = slice_iter_obj.start_loops()
if dtype.is_pyobject: if dtype.is_pyobject:
code.putln("Py_DECREF((PyObject *) %s);" % p) code.putln("Py_DECREF((PyObject *) %s);" % p)
...@@ -480,6 +483,7 @@ def assign_scalar(dst, scalar, code): ...@@ -480,6 +483,7 @@ def assign_scalar(dst, scalar, code):
if dtype.is_pyobject: if dtype.is_pyobject:
code.putln("Py_INCREF(__pyx_temp_scalar);") code.putln("Py_INCREF(__pyx_temp_scalar);")
slice_iter_obj.end_loops()
code.end_block() code.end_block()
def slice_iter(slice_type, slice_temp, ndim, code): def slice_iter(slice_type, slice_temp, ndim, code):
...@@ -496,7 +500,7 @@ class SliceIter(object): ...@@ -496,7 +500,7 @@ class SliceIter(object):
self.ndim = ndim self.ndim = ndim
class ContigSliceIter(SliceIter): class ContigSliceIter(SliceIter):
def __enter__(self): def start_loops(self):
code = self.code code = self.code
code.begin_block() code.begin_block()
...@@ -514,13 +518,13 @@ class ContigSliceIter(SliceIter): ...@@ -514,13 +518,13 @@ class ContigSliceIter(SliceIter):
return "__pyx_temp_pointer" return "__pyx_temp_pointer"
def __exit__(self, *args): def end_loops(self):
self.code.putln("__pyx_temp_pointer += 1;") self.code.putln("__pyx_temp_pointer += 1;")
self.code.putln("}") self.code.putln("}")
self.code.end_block() self.code.end_block()
class StridedSliceIter(SliceIter): class StridedSliceIter(SliceIter):
def __enter__(self): def start_loops(self):
code = self.code code = self.code
code.begin_block() code.begin_block()
...@@ -543,7 +547,7 @@ class StridedSliceIter(SliceIter): ...@@ -543,7 +547,7 @@ class StridedSliceIter(SliceIter):
return "__pyx_temp_pointer_%d" % (self.ndim - 1) return "__pyx_temp_pointer_%d" % (self.ndim - 1)
def __exit__(self, *args): def end_loops(self):
code = self.code code = self.code
for i in range(self.ndim - 1, -1, -1): for i in range(self.ndim - 1, -1, -1):
code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i)) code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i))
......
...@@ -403,6 +403,7 @@ cdef class memoryview(object): ...@@ -403,6 +403,7 @@ cdef class memoryview(object):
# It would be easy to support indirect dimensions, but it's easier # It would be easy to support indirect dimensions, but it's easier
# to disallow :) # to disallow :)
if self.view.suboffsets != NULL:
assert_direct_dimensions(self.view.suboffsets, self.view.ndim) assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
slice_assign_scalar(dst_slice, self.view.ndim, self.view.itemsize, slice_assign_scalar(dst_slice, self.view.ndim, self.view.itemsize,
item, self.dtype_is_object) item, self.dtype_is_object)
...@@ -973,14 +974,22 @@ cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview, ...@@ -973,14 +974,22 @@ cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview,
@cname('__pyx_memoryview_slice_copy') @cname('__pyx_memoryview_slice_copy')
cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst): cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst):
cdef int dim cdef int dim
cdef Py_ssize_t *shape, *strides, *suboffsets
shape = memview.view.shape
strides = memview.view.strides
suboffsets = memview.view.suboffsets
dst.memview = <__pyx_memoryview *> memview dst.memview = <__pyx_memoryview *> memview
dst.data = <char *> memview.view.buf dst.data = <char *> memview.view.buf
for dim in range(memview.view.ndim): for dim in range(memview.view.ndim):
dst.shape[dim] = memview.view.shape[dim] dst.shape[dim] = shape[dim]
dst.strides[dim] = memview.view.strides[dim] dst.strides[dim] = strides[dim]
dst.suboffsets[dim] = memview.view.suboffsets[dim] if suboffsets == NULL:
dst.suboffsets[dim] = -1
else:
dst.suboffsets[dim] = suboffsets[dim]
@cname('__pyx_memoryview_copy_object') @cname('__pyx_memoryview_copy_object')
cdef memoryview_copy(memoryview memview): cdef memoryview_copy(memoryview memview):
......
...@@ -189,20 +189,23 @@ def test_transpose(): ...@@ -189,20 +189,23 @@ def test_transpose():
print a[3, 2], a.T[2, 3], a_obj[3, 2], a_obj.T[2, 3], numpy_obj[3, 2], numpy_obj.T[2, 3] print a[3, 2], a.T[2, 3], a_obj[3, 2], a_obj.T[2, 3], numpy_obj[3, 2], numpy_obj.T[2, 3]
@testcase @testcase_numpy_1_5
def test_numpy_like_attributes(cyarray): def test_numpy_like_attributes(cyarray):
""" """
For some reason this fails in numpy 1.4, with shape () and strides (40, 8)
instead of 20, 4 on my machine. Investigate this.
>>> cyarray = create_array(shape=(8, 5), mode="c") >>> cyarray = create_array(shape=(8, 5), mode="c")
>>> test_numpy_like_attributes(cyarray) >>> test_numpy_like_attributes(cyarray)
>>> test_numpy_like_attributes(cyarray.memview) >>> test_numpy_like_attributes(cyarray.memview)
""" """
numarray = np.asarray(cyarray) numarray = np.asarray(cyarray)
assert cyarray.shape == numarray.shape assert cyarray.shape == numarray.shape, (cyarray.shape, numarray.shape)
assert cyarray.strides == numarray.strides assert cyarray.strides == numarray.strides, (cyarray.strides, numarray.strides)
assert cyarray.ndim == numarray.ndim assert cyarray.ndim == numarray.ndim, (cyarray.ndim, numarray.ndim)
assert cyarray.size == numarray.size assert cyarray.size == numarray.size, (cyarray.size, numarray.size)
assert cyarray.nbytes == numarray.nbytes assert cyarray.nbytes == numarray.nbytes, (cyarray.nbytes, numarray.nbytes)
cdef int[:, :] mslice = numarray cdef int[:, :] mslice = numarray
assert (<object> mslice).base is numarray assert (<object> mslice).base is numarray
......
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