Skip to content

Commit 2705f4c

Browse files
committed
objlist: Implement growing slice assignment.
This means that complete slice operations are supported for lists (but not for bytearray's and array.array's).
1 parent 69d081a commit 2705f4c

3 files changed

Lines changed: 47 additions & 5 deletions

File tree

py/obj.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,3 +578,8 @@ mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
578578
memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \
579579
/*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \
580580
memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));
581+
582+
#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_t) \
583+
/*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t));*/ \
584+
memmove(dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t)); \
585+
memcpy(dest + beg, slice, slice_len * sizeof(item_t));

py/objlist.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,21 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
199199
}
200200
int len_adj = slice->len - (stop - start);
201201
//printf("Len adj: %d\n", len_adj);
202-
assert(len_adj <= 0);
203-
mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t);
204-
// Clear "freed" elements at the end of list
205-
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
202+
if (len_adj > 0) {
203+
if (self->len + len_adj > self->alloc) {
204+
// TODO: Might optimize memory copies here by checking if block can
205+
// be grown inplace or not
206+
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj);
207+
self->alloc = self->len + len_adj;
208+
}
209+
mp_seq_replace_slice_grow_inplace(self->items, self->len, start, stop, slice->items, slice->len, len_adj, mp_obj_t);
210+
} else {
211+
mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t);
212+
// Clear "freed" elements at the end of list
213+
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
214+
// TODO: apply allocation policy re: alloc_size
215+
}
206216
self->len += len_adj;
207-
// TODO: apply allocation policy re: alloc_size
208217
return mp_const_none;
209218
}
210219
#endif
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
x = list(range(2))
2+
3+
l = list(x)
4+
l[0:0] = [10]
5+
print(l)
6+
l = list(x)
7+
l[:0] = [10, 20]
8+
print(l)
9+
l = list(x)
10+
l[0:0] = [10, 20, 30, 40]
11+
print(l)
12+
13+
l = list(x)
14+
l[1:1] = [10, 20, 30, 40]
15+
print(l)
16+
17+
l = list(x)
18+
l[2:] = [10, 20, 30, 40]
19+
print(l)
20+
21+
# Weird cases
22+
l = list(x)
23+
l[1:0] = [10, 20, 30, 40]
24+
print(l)
25+
26+
l = list(x)
27+
l[100:100] = [10, 20, 30, 40]
28+
print(l)

0 commit comments

Comments
 (0)