summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/obj.h1
-rw-r--r--py/objstr.c22
-rw-r--r--py/sequence.c30
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;
+}