From 2705f4c782292eeb0b5ce77aadd1a1ea8a106164 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 25 May 2014 02:36:12 +0300 Subject: objlist: Implement growing slice assignment. This means that complete slice operations are supported for lists (but not for bytearray's and array.array's). --- py/obj.h | 5 +++++ py/objlist.c | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'py') diff --git a/py/obj.h b/py/obj.h index 5f2b9d3be..611873d2e 100644 --- a/py/obj.h +++ b/py/obj.h @@ -578,3 +578,8 @@ mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value); memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \ /*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \ memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t)); + +#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_t) \ + /*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t));*/ \ + memmove(dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t)); \ + memcpy(dest + beg, slice, slice_len * sizeof(item_t)); diff --git a/py/objlist.c b/py/objlist.c index 7a15006ad..7d9f56d2e 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -199,12 +199,21 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } int len_adj = slice->len - (stop - start); //printf("Len adj: %d\n", len_adj); - assert(len_adj <= 0); - mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t); - // Clear "freed" elements at the end of list - mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); + if (len_adj > 0) { + if (self->len + len_adj > self->alloc) { + // TODO: Might optimize memory copies here by checking if block can + // be grown inplace or not + self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj); + self->alloc = self->len + len_adj; + } + mp_seq_replace_slice_grow_inplace(self->items, self->len, start, stop, slice->items, slice->len, len_adj, mp_obj_t); + } else { + mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t); + // Clear "freed" elements at the end of list + mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); + // TODO: apply allocation policy re: alloc_size + } self->len += len_adj; - // TODO: apply allocation policy re: alloc_size return mp_const_none; } #endif -- cgit v1.2.3