py/objlist: Reduce code size in slice operations.
By refactoring the code to separate out the slicing operation from the regular indexing operation, code can be shared between the various types of slice operations (read/assign/delete). Signed-off-by: Jeff Epler <jepler@gmail.com>
This commit is contained in:
committed by
Damien George
parent
0ef5ede382
commit
73b1cbc17a
63
py/objlist.c
63
py/objlist.c
@@ -159,56 +159,32 @@ static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||||
if (value == MP_OBJ_NULL) {
|
|
||||||
// delete
|
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
if (mp_obj_is_type(index, &mp_type_slice)) {
|
if (mp_obj_is_type(index, &mp_type_slice)) {
|
||||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_bound_slice_t slice;
|
mp_bound_slice_t slice;
|
||||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
|
bool fast = mp_seq_get_fast_slice_indexes(self->len, index, &slice);
|
||||||
mp_raise_NotImplementedError(NULL);
|
if (value == MP_OBJ_SENTINEL) {
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t len_adj = slice.start - slice.stop;
|
|
||||||
assert(len_adj <= 0);
|
|
||||||
mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items /*NULL*/, 0, sizeof(*self->items));
|
|
||||||
// Clear "freed" elements at the end of list
|
|
||||||
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
|
||||||
self->len += len_adj;
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
mp_obj_t args[2] = {self_in, index};
|
|
||||||
list_pop(2, args);
|
|
||||||
return mp_const_none;
|
|
||||||
} else if (value == MP_OBJ_SENTINEL) {
|
|
||||||
// load
|
// load
|
||||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
if (!fast) {
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
|
||||||
if (mp_obj_is_type(index, &mp_type_slice)) {
|
|
||||||
mp_bound_slice_t slice;
|
|
||||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
|
|
||||||
return mp_seq_extract_slice(self->items, &slice);
|
return mp_seq_extract_slice(self->items, &slice);
|
||||||
}
|
}
|
||||||
mp_obj_list_t *res = list_new(slice.stop - slice.start);
|
mp_obj_list_t *res = list_new(slice.stop - slice.start);
|
||||||
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
|
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
|
||||||
return MP_OBJ_FROM_PTR(res);
|
return MP_OBJ_FROM_PTR(res);
|
||||||
}
|
}
|
||||||
#endif
|
// assign/delete
|
||||||
size_t index_val = mp_get_index(self->base.type, self->len, index, false);
|
if (value == MP_OBJ_NULL) {
|
||||||
return self->items[index_val];
|
// delete is equivalent to slice assignment of an empty sequence
|
||||||
} else {
|
value = mp_const_empty_tuple;
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
}
|
||||||
if (mp_obj_is_type(index, &mp_type_slice)) {
|
if (!fast) {
|
||||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_raise_NotImplementedError(NULL);
|
||||||
|
}
|
||||||
size_t value_len;
|
size_t value_len;
|
||||||
mp_obj_t *value_items;
|
mp_obj_t *value_items;
|
||||||
mp_obj_get_array(value, &value_len, &value_items);
|
mp_obj_get_array(value, &value_len, &value_items);
|
||||||
mp_bound_slice_t slice_out;
|
mp_int_t len_adj = value_len - (slice.stop - slice.start);
|
||||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) {
|
|
||||||
mp_raise_NotImplementedError(NULL);
|
|
||||||
}
|
|
||||||
mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start);
|
|
||||||
if (len_adj > 0) {
|
if (len_adj > 0) {
|
||||||
if (self->len + len_adj > self->alloc) {
|
if (self->len + len_adj > self->alloc) {
|
||||||
// TODO: Might optimize memory copies here by checking if block can
|
// TODO: Might optimize memory copies here by checking if block can
|
||||||
@@ -217,10 +193,10 @@ static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||||||
self->alloc = self->len + len_adj;
|
self->alloc = self->len + len_adj;
|
||||||
}
|
}
|
||||||
mp_seq_replace_slice_grow_inplace(self->items, self->len,
|
mp_seq_replace_slice_grow_inplace(self->items, self->len,
|
||||||
slice_out.start, slice_out.stop, value_items, value_len, len_adj, sizeof(*self->items));
|
slice.start, slice.stop, value_items, value_len, len_adj, sizeof(*self->items));
|
||||||
} else {
|
} else {
|
||||||
mp_seq_replace_slice_no_grow(self->items, self->len,
|
mp_seq_replace_slice_no_grow(self->items, self->len,
|
||||||
slice_out.start, slice_out.stop, value_items, value_len, sizeof(*self->items));
|
slice.start, slice.stop, value_items, value_len, sizeof(*self->items));
|
||||||
// Clear "freed" elements at the end of list
|
// Clear "freed" elements at the end of list
|
||||||
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
||||||
// TODO: apply allocation policy re: alloc_size
|
// TODO: apply allocation policy re: alloc_size
|
||||||
@@ -229,6 +205,17 @@ static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (value == MP_OBJ_NULL) {
|
||||||
|
// delete
|
||||||
|
mp_obj_t args[2] = {self_in, index};
|
||||||
|
list_pop(2, args);
|
||||||
|
return mp_const_none;
|
||||||
|
} else if (value == MP_OBJ_SENTINEL) {
|
||||||
|
// load
|
||||||
|
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
size_t index_val = mp_get_index(self->base.type, self->len, index, false);
|
||||||
|
return self->items[index_val];
|
||||||
|
} else {
|
||||||
mp_obj_list_store(self_in, index, value);
|
mp_obj_list_store(self_in, index, value);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user