summaryrefslogtreecommitdiff
path: root/py/obj.h
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
committerScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
commit30ee7019ca651bce1fe966c1089fe977d51dc92b (patch)
tree0114b6f744dd175b7722dd8edcbe24f4ee84bb45 /py/obj.h
parent97fcdfbd08c922efd7470d6482d7c7c703ffc0ae (diff)
parent869cdcfdfc860b1177baf9b0f8818915ba54f3f5 (diff)
Merge tag 'v1.9.1'2.0.0-alpha.0
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions This release provides an important fix for the USB mass storage device in the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which is now require by some Operating Systems. There are also fixes for the lwIP bindings to improve non-blocking sockets and error codes. The VFS has some regressions fixed including the ability to statvfs the root. All changes are listed below. py core: - modbuiltins: add core-provided version of input() function - objstr: catch case of negative "maxsplit" arg to str.rsplit() - persistentcode: allow to compile with complex numbers disabled - objstr: allow to compile with obj-repr D, and unicode disabled - modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled - provide mp_decode_uint_skip() to help reduce stack usage - makeqstrdefs.py: make script run correctly with Python 2.6 - objstringio: if created from immutable object, follow copy on write policy extmod: - modlwip: connect: for non-blocking mode, return EINPROGRESS - modlwip: fix error codes for duplicate calls to connect() - modlwip: accept: fix error code for non-blocking mode - vfs: allow to statvfs the root directory - vfs: allow "buffering" and "encoding" args to VFS's open() - modframebuf: fix signed/unsigned comparison pendantic warning lib: - libm: use isfinite instead of finitef, for C99 compatibility - utils/interrupt_char: remove support for KBD_EXCEPTION disabled tests: - basics/string_rsplit: add tests for negative "maxsplit" argument - float: convert "sys.exit()" to "raise SystemExit" - float/builtin_float_minmax: PEP8 fixes - basics: convert "sys.exit()" to "raise SystemExit" - convert remaining "sys.exit()" to "raise SystemExit" unix port: - convert to use core-provided version of built-in import() - Makefile: replace references to make with $(MAKE) windows port: - convert to use core-provided version of built-in import() qemu-arm port: - Makefile: adjust object-file lists to get correct dependencies - enable micropython.mem_*() functions to allow more tests stmhal port: - boards: enable DAC for NUCLEO_F767ZI board - add support for NUCLEO_F446RE board - pass USB handler as parameter to allow more than one USB handler - usb: use local USB handler variable in Start-of-Frame handler - usb: make state for USB device private to top-level USB driver - usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command - convert from using stmhal's input() to core provided version cc3200 port: - convert from using stmhal's input() to core provided version teensy port: - convert from using stmhal's input() to core provided version esp8266 port: - Makefile: replace references to make with $(MAKE) - Makefile: add clean-modules target - convert from using stmhal's input() to core provided version zephyr port: - modusocket: getaddrinfo: Fix mp_obj_len() usage - define MICROPY_PY_SYS_PLATFORM (to "zephyr") - machine_pin: use native Zephyr types for Zephyr API calls docs: - machine.Pin: remove out_value() method - machine.Pin: add on() and off() methods - esp8266: consistently replace Pin.high/low methods with .on/off - esp8266/quickref: polish Pin.on()/off() examples - network: move confusingly-named cc3200 Server class to its reference - uos: deconditionalize, remove minor port-specific details - uos: move cc3200 port legacy VFS mounting functions to its ref doc - machine: sort machine classes in logical order, not alphabetically - network: first step to describe standard network class interface examples: - embedding: use core-provided KeyboardInterrupt object
Diffstat (limited to 'py/obj.h')
-rw-r--r--py/obj.h172
1 files changed, 102 insertions, 70 deletions
diff --git a/py/obj.h b/py/obj.h
index a794e0e95..b43636080 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -355,11 +355,11 @@ typedef struct _mp_rom_map_elem_t {
// would also need a trucated dict structure
typedef struct _mp_map_t {
- mp_uint_t all_keys_are_qstrs : 1;
- mp_uint_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered
- mp_uint_t is_ordered : 1; // an ordered array
- mp_uint_t used : (8 * sizeof(mp_uint_t) - 3);
- mp_uint_t alloc;
+ size_t all_keys_are_qstrs : 1;
+ size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered
+ size_t is_ordered : 1; // an ordered array
+ size_t used : (8 * sizeof(size_t) - 3);
+ size_t alloc;
mp_map_elem_t *table;
} mp_map_t;
@@ -373,11 +373,11 @@ typedef enum _mp_map_lookup_kind_t {
extern const mp_map_t mp_const_empty_map;
-static inline bool MP_MAP_SLOT_IS_FILLED(const mp_map_t *map, mp_uint_t pos) { return ((map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL); }
+static inline bool MP_MAP_SLOT_IS_FILLED(const mp_map_t *map, size_t pos) { return ((map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL); }
-void mp_map_init(mp_map_t *map, mp_uint_t n);
-void mp_map_init_fixed_table(mp_map_t *map, mp_uint_t n, const mp_obj_t *table);
-mp_map_t *mp_map_new(mp_uint_t n);
+void mp_map_init(mp_map_t *map, size_t n);
+void mp_map_init_fixed_table(mp_map_t *map, size_t n, const mp_obj_t *table);
+mp_map_t *mp_map_new(size_t n);
void mp_map_deinit(mp_map_t *map);
void mp_map_free(mp_map_t *map);
mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
@@ -387,14 +387,14 @@ void mp_map_dump(mp_map_t *map);
// Underlying set implementation (not set object)
typedef struct _mp_set_t {
- mp_uint_t alloc;
- mp_uint_t used;
+ size_t alloc;
+ size_t used;
mp_obj_t *table;
} mp_set_t;
-static inline bool MP_SET_SLOT_IS_FILLED(const mp_set_t *set, mp_uint_t pos) { return ((set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL); }
+static inline bool MP_SET_SLOT_IS_FILLED(const mp_set_t *set, size_t pos) { return ((set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL); }
-void mp_set_init(mp_set_t *set, mp_uint_t n);
+void mp_set_init(mp_set_t *set, size_t n);
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
mp_obj_t mp_set_remove_first(mp_set_t *set);
void mp_set_clear(mp_set_t *set);
@@ -419,6 +419,15 @@ typedef enum {
PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses
} mp_print_kind_t;
+typedef struct _mp_obj_iter_buf_t {
+ mp_obj_base_t base;
+ mp_obj_t buf[3];
+} mp_obj_iter_buf_t;
+
+// The number of slots that an mp_obj_iter_buf_t needs on the Python value stack.
+// It's rounded up in case mp_obj_base_t is smaller than mp_obj_t (eg for OBJ_REPR_D).
+#define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_t))
+
typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args);
@@ -426,6 +435,7 @@ typedef mp_obj_t (*mp_unary_op_fun_t)(mp_uint_t op, mp_obj_t);
typedef mp_obj_t (*mp_binary_op_fun_t)(mp_uint_t op, mp_obj_t, mp_obj_t);
typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
+typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
// Buffer protocol
typedef struct _mp_buffer_info_t {
@@ -462,16 +472,27 @@ typedef struct _mp_stream_p_t {
} mp_stream_p_t;
struct _mp_obj_type_t {
+ // A type is an object so must start with this entry, which points to mp_type_type.
mp_obj_base_t base;
+
+ // The name of this type.
qstr name;
+
+ // Corresponds to __repr__ and __str__ special methods.
mp_print_fun_t print;
- mp_make_new_fun_t make_new; // to make an instance of the type
+ // Corresponds to __new__ and __init__ special methods, to make an instance of the type.
+ mp_make_new_fun_t make_new;
+
+ // Corresponds to __call__ special method, ie T(...).
mp_call_fun_t call;
- mp_unary_op_fun_t unary_op; // can return MP_OBJ_NULL if op not supported
- mp_binary_op_fun_t binary_op; // can return MP_OBJ_NULL if op not supported
- // implements load, store and delete attribute
+ // Implements unary and binary operations.
+ // Can return MP_OBJ_NULL if the operation is not supported.
+ mp_unary_op_fun_t unary_op;
+ mp_binary_op_fun_t binary_op;
+
+ // Implements load, store and delete attribute.
//
// dest[0] = MP_OBJ_NULL means load
// return: for fail, do nothing
@@ -484,31 +505,36 @@ struct _mp_obj_type_t {
// for success set dest[0] = MP_OBJ_NULL
mp_attr_fun_t attr;
- mp_subscr_fun_t subscr; // implements load, store, delete subscripting
- // value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store
- // can return MP_OBJ_NULL if op not supported
+ // Implements load, store and delete subscripting:
+ // - value = MP_OBJ_SENTINEL means load
+ // - value = MP_OBJ_NULL means delete
+ // - all other values mean store the value
+ // Can return MP_OBJ_NULL if operation not supported.
+ mp_subscr_fun_t subscr;
+
+ // Corresponds to __iter__ special method.
+ // Can use the given mp_obj_iter_buf_t to store iterator object,
+ // otherwise can return a pointer to an object on the heap.
+ mp_getiter_fun_t getiter;
- mp_fun_1_t getiter; // corresponds to __iter__ special method
- mp_fun_1_t iternext; // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration() (with no args)
+ // Corresponds to __next__ special method. May return MP_OBJ_STOP_ITERATION
+ // as an optimisation instead of raising StopIteration() with no args.
+ mp_fun_1_t iternext;
+ // Implements the buffer protocol if supported by this type.
mp_buffer_p_t buffer_p;
+
// One of disjoint protocols (interfaces), like mp_stream_p_t, etc.
const void *protocol;
- // these are for dynamically created types (classes)
- struct _mp_obj_tuple_t *bases_tuple;
- struct _mp_obj_dict_t *locals_dict;
-
- /*
- What we might need to add here:
-
- len str tuple list map
- abs float complex
- hash bool int none str
- equal int str
+ // A pointer to the parents of this type:
+ // - 0 parents: pointer is NULL (object is implicitly the single parent)
+ // - 1 parent: a pointer to the type of that parent
+ // - 2 or more parents: pointer to a tuple object containing the parent types
+ const void *parent;
- unpack seq list tuple
- */
+ // A dict mapping qstrs to objects local methods/constants/etc.
+ struct _mp_obj_dict_t *locals_dict;
};
// Constant types, globally accessible
@@ -607,40 +633,39 @@ static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true :
mp_obj_t mp_obj_new_cell(mp_obj_t obj);
mp_obj_t mp_obj_new_int(mp_int_t value);
mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value);
-mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base);
+mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base);
mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception)
-mp_obj_t mp_obj_new_str(const char* data, mp_uint_t len, bool make_qstr_if_not_already);
+mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already);
mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr);
-mp_obj_t mp_obj_new_bytes(const byte* data, mp_uint_t len);
-mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items);
-mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items);
+mp_obj_t mp_obj_new_bytes(const byte* data, size_t len);
+mp_obj_t mp_obj_new_bytearray(size_t n, void *items);
+mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items);
#if MICROPY_PY_BUILTINS_FLOAT
mp_obj_t mp_obj_new_int_from_float(mp_float_t val);
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
#endif
mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type);
mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg);
-mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args);
+mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args);
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg);
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const char *fmt, va_list ap); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table);
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table);
-mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig);
-mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig);
+mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig);
+mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig);
mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
-mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed);
-mp_obj_t mp_obj_new_tuple(mp_uint_t n, const mp_obj_t *items);
-mp_obj_t mp_obj_new_list(mp_uint_t n, mp_obj_t *items);
-mp_obj_t mp_obj_new_dict(mp_uint_t n_args);
-mp_obj_t mp_obj_new_set(mp_uint_t n_args, mp_obj_t *items);
+mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed);
+mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items);
+mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items);
+mp_obj_t mp_obj_new_dict(size_t n_args);
+mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items);
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
-mp_obj_t mp_obj_new_super(mp_obj_t type, mp_obj_t obj);
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self);
-mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args);
+mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf);
mp_obj_t mp_obj_new_module(qstr module_name);
-mp_obj_t mp_obj_new_memoryview(byte typecode, mp_uint_t nitems, void *items);
+mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items);
mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in);
const char *mp_obj_get_type_str(mp_const_obj_t o_in);
@@ -663,9 +688,9 @@ mp_float_t mp_obj_get_float(mp_obj_t self_in);
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
#endif
//qstr mp_obj_get_qstr(mp_obj_t arg);
-void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items); // *items may point inside a GC block
-void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items); // *items may point inside a GC block
-mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, bool is_slice);
+void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items); // *items may point inside a GC block
+void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items); // *items may point inside a GC block
+size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice);
mp_obj_t mp_obj_id(mp_obj_t o_in);
mp_obj_t mp_obj_len(mp_obj_t o_in);
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL
@@ -699,12 +724,17 @@ void mp_init_emergency_exception_buf(void);
bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2);
qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
-const char *mp_obj_str_get_data(mp_obj_t self_in, mp_uint_t *len);
+const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len);
mp_obj_t mp_obj_str_intern(mp_obj_t str);
-void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_t str_len, bool is_bytes);
+void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t str_len, bool is_bytes);
#if MICROPY_PY_BUILTINS_FLOAT
// float
+#if MICROPY_FLOAT_HIGH_QUALITY_HASH
+mp_int_t mp_float_hash(mp_float_t val);
+#else
+static inline mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; }
+#endif
mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported
// complex
@@ -715,17 +745,17 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t
#endif
// tuple
-void mp_obj_tuple_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items);
+void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items);
void mp_obj_tuple_del(mp_obj_t self_in);
mp_int_t mp_obj_tuple_hash(mp_obj_t self_in);
// list
struct _mp_obj_list_t;
-void mp_obj_list_init(struct _mp_obj_list_t *o, mp_uint_t n);
+void mp_obj_list_init(struct _mp_obj_list_t *o, size_t n);
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg);
mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value);
-void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items);
-void mp_obj_list_set_len(mp_obj_t self_in, mp_uint_t len);
+void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items);
+void mp_obj_list_set_len(mp_obj_t self_in, size_t len);
void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
@@ -734,8 +764,8 @@ typedef struct _mp_obj_dict_t {
mp_obj_base_t base;
mp_map_t map;
} mp_obj_dict_t;
-void mp_obj_dict_init(mp_obj_dict_t *dict, mp_uint_t n_args);
-mp_uint_t mp_obj_dict_len(mp_obj_t self_in);
+void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args);
+size_t mp_obj_dict_len(mp_obj_t self_in);
mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index);
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key);
@@ -776,6 +806,7 @@ qstr mp_obj_code_get_name(const byte *code_info);
mp_obj_t mp_identity(mp_obj_t self);
MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj);
+mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf);
// module
typedef struct _mp_obj_module_t {
@@ -809,17 +840,17 @@ typedef struct {
mp_int_t step;
} mp_bound_slice_t;
-void mp_seq_multiply(const void *items, mp_uint_t item_sz, mp_uint_t len, mp_uint_t times, void *dest);
+void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest);
#if MICROPY_PY_BUILTINS_SLICE
bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes);
#endif
#define mp_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t))
#define mp_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, (len1) * sizeof(item_t)); memcpy(dest + (len1), src2, (len2) * sizeof(item_t)); }
-bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byte *data2, mp_uint_t len2);
-bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const mp_obj_t *items2, mp_uint_t len2);
-mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args, const mp_obj_t *args);
-mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value);
-mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
+bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, size_t len1, const byte *data2, size_t len2);
+bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp_obj_t *items2, size_t len2);
+mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args);
+mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value);
+mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
#define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte*)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz))
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_sz) \
@@ -828,9 +859,10 @@ mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice
/*printf("memmove(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * (item_sz));*/ \
memmove(((char*)dest) + (beg + slice_len) * (item_sz), ((char*)dest) + (end) * (item_sz), (dest_len - end) * (item_sz));
+// Note: dest and slice regions may overlap
#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_sz) \
/*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * (item_sz));*/ \
- memmove(((char*)dest) + (beg + len_adj) * (item_sz), ((char*)dest) + (beg) * (item_sz), (dest_len - beg) * (item_sz)); \
- memcpy(((char*)dest) + (beg) * (item_sz), slice, slice_len * (item_sz));
+ memmove(((char*)dest) + (beg + slice_len) * (item_sz), ((char*)dest) + (end) * (item_sz), ((dest_len) + (len_adj) - ((beg) + (slice_len))) * (item_sz)); \
+ memmove(((char*)dest) + (beg) * (item_sz), slice, slice_len * (item_sz));
#endif // __MICROPY_INCLUDED_PY_OBJ_H__