Skip to content

Commit 4915c2b

Browse files
committed
py: Small code space optimisations for memoryview slice assigment.
Also adds #if guards to allow uPy core to compile without memoryview enabled, but with slice assignment enabled.
1 parent cceff15 commit 4915c2b

1 file changed

Lines changed: 13 additions & 9 deletions

File tree

py/objarray.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,20 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
374374
mp_uint_t src_len;
375375
void *src_items;
376376
size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
377-
if (MP_OBJ_IS_TYPE(value, &mp_type_array) || MP_OBJ_IS_TYPE(value, &mp_type_bytearray)) {
377+
if (MP_OBJ_IS_OBJ(value) && ((mp_obj_base_t*)value)->type->subscr == array_subscr) {
378+
// value is array, bytearray or memoryview
378379
mp_obj_array_t *src_slice = value;
379380
if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
380381
compat_error:
381382
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "lhs and rhs should be compatible"));
382383
}
383384
src_len = src_slice->len;
384385
src_items = src_slice->items;
386+
#if MICROPY_PY_BUILTINS_MEMORYVIEW
387+
if (MP_OBJ_IS_TYPE(value, &mp_type_memoryview)) {
388+
src_items = (uint8_t*)src_items + (src_slice->free * item_sz);
389+
}
390+
#endif
385391
} else if (MP_OBJ_IS_TYPE(value, &mp_type_bytes)) {
386392
if (item_sz != 1) {
387393
goto compat_error;
@@ -390,23 +396,18 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
390396
mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ);
391397
src_len = bufinfo.len;
392398
src_items = bufinfo.buf;
393-
} else if (MP_OBJ_IS_TYPE(value, &mp_type_memoryview)) {
394-
mp_obj_array_t *src_slice = value;
395-
if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
396-
goto compat_error;
397-
}
398-
src_len = src_slice->len;
399-
src_items = (uint8_t*)src_slice->items + (src_slice->free * item_sz);
400399
} else {
401400
mp_not_implemented("array/bytes required on right side");
402401
}
403402

404403
// TODO: check src/dst compat
405404
mp_int_t len_adj = src_len - (slice.stop - slice.start);
406405
if (len_adj > 0) {
406+
#if MICROPY_PY_BUILTINS_MEMORYVIEW
407407
if (o->base.type == &mp_type_memoryview) {
408408
goto compat_error;
409409
}
410+
#endif
410411
if (len_adj > o->free) {
411412
// TODO: alloc policy; at the moment we go conservative
412413
o->items = m_renew(byte, o->items, (o->len + o->free) * item_sz, (o->len + len_adj) * item_sz);
@@ -415,13 +416,16 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
415416
mp_seq_replace_slice_grow_inplace(o->items, o->len,
416417
slice.start, slice.stop, src_items, src_len, len_adj, item_sz);
417418
} else {
419+
#if MICROPY_PY_BUILTINS_MEMORYVIEW
418420
if (o->base.type == &mp_type_memoryview) {
419421
if (len_adj != 0) {
420422
goto compat_error;
421423
}
422424
mp_seq_replace_slice_no_grow((uint8_t*)o->items + (o->free * item_sz), o->len,
423425
slice.start, slice.stop, src_items, src_len, item_sz);
424-
} else {
426+
} else
427+
#endif
428+
{
425429
mp_seq_replace_slice_no_grow(o->items, o->len,
426430
slice.start, slice.stop, src_items, src_len, item_sz);
427431
// Clear "freed" elements at the end of list

0 commit comments

Comments
 (0)