From 7364af2d8cd72467bbb3bf135b29fae47105b232 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 2 Feb 2014 02:38:22 +0200 Subject: [PATCH] Factor out m_seq_get_fast_slice_indexes() fucntions as sequence helper. Takes slice object and sequence length and computes subsequence indexes for case of slice step=1. --- py/obj.h | 1 + py/objstr.c | 22 ++-------------------- py/sequence.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/py/obj.h b/py/obj.h index 0680e6fb1c..45430d4a1c 100644 --- a/py/obj.h +++ b/py/obj.h @@ -395,3 +395,4 @@ typedef struct _mp_obj_classmethod_t { // sequence helpers void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest); +bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end); diff --git a/py/objstr.c b/py/objstr.c index 3f6aa483e2..92bd71f3de 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -115,26 +115,8 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } #if MICROPY_ENABLE_SLICE } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { - machine_int_t start, stop, step; - mp_obj_slice_get(rhs_in, &start, &stop, &step); - assert(step == 1); - if (start < 0) { - start = lhs_len + start; - if (start < 0) { - start = 0; - } - } else if (start > lhs_len) { - start = lhs_len; - } - if (stop <= 0) { - stop = lhs_len + stop; - // CPython returns empty string in such case - if (stop < 0) { - stop = start; - } - } else if (stop > lhs_len) { - stop = lhs_len; - } + machine_uint_t start, stop; + assert(m_seq_get_fast_slice_indexes(lhs_len, rhs_in, &start, &stop)); return mp_obj_new_str(lhs_data + start, stop - start, false); #endif } else { diff --git a/py/sequence.c b/py/sequence.c index 56718c6f85..1e851a9f80 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -23,3 +23,33 @@ void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void dest = (char*)dest + copy_sz; } } + +bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end) { + machine_int_t start, stop, step; + mp_obj_slice_get(slice, &start, &stop, &step); + if (step != 1) { + return false; + } + + // Unlike subscription, out-of-bounds slice indexes are never error + if (start < 0) { + start = len + start; + if (start < 0) { + start = 0; + } + } else if (start > len) { + start = len; + } + if (stop <= 0) { + stop = len + stop; + // CPython returns empty sequence in such case + if (stop < 0) { + stop = start; + } + } else if (stop > len) { + stop = len; + } + *begin = start; + *end = stop; + return true; +}