summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2020-07-16 23:23:42 +1000
committerDamien George <damien@micropython.org>2020-07-21 01:05:59 +1000
commita853fff838c1f995b9eeb0ebef5f117cfa3d5f0a (patch)
treea3787700c5911ea7ba9f3f18d43b0813224cecfe
parent895b1dbdda132b115bb0b5102962f4f46adb7adb (diff)
py/obj.h: Fix mp_seq_replace_slice_no_grow to use memmove not memcpy.
Because the argument arrays may overlap, as show by the new tests in this commit. Also remove the debugging comments for these macros, add a new comment about overlapping regions, and separate the macros by blank lines to make them easier to read. Fixes issue #6244. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--py/obj.h8
-rw-r--r--tests/basics/memoryview_slice_assign.py24
2 files changed, 28 insertions, 4 deletions
diff --git a/py/obj.h b/py/obj.h
index f621b1dad..31542a7f9 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -992,17 +992,17 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp
mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args);
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value);
mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
+
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
#define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte *)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz))
+
+// Note: dest and slice regions may overlap
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_sz) \
- /*printf("memcpy(%p, %p, %d)\n", dest + beg, slice, slice_len * (item_sz));*/ \
- memcpy(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \
- /*printf("memmove(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * (item_sz));*/ \
+ memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \
memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), (dest_len - end) * (item_sz));
// Note: dest and slice regions may overlap
#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_sz) \
- /*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * (item_sz));*/ \
memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), ((dest_len) + (len_adj) - ((beg) + (slice_len))) * (item_sz)); \
memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz));
diff --git a/tests/basics/memoryview_slice_assign.py b/tests/basics/memoryview_slice_assign.py
index b730dceba..74f6fae6f 100644
--- a/tests/basics/memoryview_slice_assign.py
+++ b/tests/basics/memoryview_slice_assign.py
@@ -61,3 +61,27 @@ try:
memoryview(array.array('i'))[0:2] = b'1234'
except ValueError:
print('ValueError')
+
+# test shift left of bytearray
+b = bytearray(range(10))
+mv = memoryview(b)
+mv[1:] = mv[:-1]
+print(b)
+
+# test shift right of bytearray
+b = bytearray(range(10))
+mv = memoryview(b)
+mv[:-1] = mv[1:]
+print(b)
+
+# test shift left of array
+a = array.array('I', range(10))
+mv = memoryview(a)
+mv[1:] = mv[:-1]
+print(a)
+
+# test shift right of array
+a = array.array('I', range(10))
+mv = memoryview(a)
+mv[:-1] = mv[1:]
+print(a)