summaryrefslogtreecommitdiff
path: root/py/objarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/objarray.c')
-rw-r--r--py/objarray.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/py/objarray.c b/py/objarray.c
index 1fff23482..803af2cd2 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -424,6 +424,13 @@ static mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) {
if (self->free < len) {
self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz);
self->free = 0;
+
+ if (self_in == arg_in) {
+ // Get arg_bufinfo again in case self->items has moved
+ //
+ // (Note not possible to handle case that arg_in is a memoryview into self)
+ mp_get_buffer_raise(arg_in, &arg_bufinfo, MP_BUFFER_READ);
+ }
} else {
self->free -= len;
}
@@ -456,7 +463,8 @@ static mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
#if MICROPY_PY_ARRAY_SLICE_ASSIGN
// Assign
size_t src_len;
- void *src_items;
+ uint8_t *src_items;
+ size_t src_offs = 0;
size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
if (mp_obj_is_obj(value) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type, subscr) == array_subscr) {
// value is array, bytearray or memoryview
@@ -469,7 +477,7 @@ static mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
src_items = src_slice->items;
#if MICROPY_PY_BUILTINS_MEMORYVIEW
if (mp_obj_is_type(value, &mp_type_memoryview)) {
- src_items = (uint8_t *)src_items + (src_slice->memview_offset * item_sz);
+ src_offs = src_slice->memview_offset * item_sz;
}
#endif
} else if (mp_obj_is_type(value, &mp_type_bytes)) {
@@ -504,13 +512,17 @@ static mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
// TODO: alloc policy; at the moment we go conservative
o->items = m_renew(byte, o->items, (o->len + o->free) * item_sz, (o->len + len_adj) * item_sz);
o->free = len_adj;
+ // m_renew may have moved o->items
+ if (src_items == dest_items) {
+ src_items = o->items;
+ }
dest_items = o->items;
}
mp_seq_replace_slice_grow_inplace(dest_items, o->len,
- slice.start, slice.stop, src_items, src_len, len_adj, item_sz);
+ slice.start, slice.stop, src_items + src_offs, src_len, len_adj, item_sz);
} else {
mp_seq_replace_slice_no_grow(dest_items, o->len,
- slice.start, slice.stop, src_items, src_len, item_sz);
+ slice.start, slice.stop, src_items + src_offs, src_len, item_sz);
// Clear "freed" elements at the end of list
// TODO: This is actually only needed for typecode=='O'
mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz);