py/objstr: Consolidate methods for str/bytes/bytearray/array.

This commit adds the bytes methods to bytearray, matching CPython.  The
existing implementations of these methods for str/bytes are reused for
bytearray with minor updates to match CPython return types.

For details on the CPython behaviour see
https://docs.python.org/3/library/stdtypes.html#bytes-and-bytearray-operations

The work to merge locals tables for str/bytes/bytearray/array was done by
@jimmo.  Because of this merging of locals the change in code size for this
commit is mostly negative:

       bare-arm:    +0 +0.000%
    minimal x86:   +29 +0.018%
       unix x64:  -792 -0.128% standard[incl -448(data)]
    unix nanbox:  -436 -0.078% nanbox[incl -448(data)]
          stm32:   -40 -0.010% PYBV10
         cc3200:   -32 -0.017%
        esp8266:   -28 -0.004% GENERIC
          esp32:   -72 -0.005% GENERIC[incl -200(data)]
         mimxrt:   -40 -0.011% TEENSY40
     renesas-ra:   -40 -0.006% RA6M2_EK
            nrf:   -16 -0.009% pca10040
            rp2:   -64 -0.013% PICO
           samd:  +148 +0.105% ADAFRUIT_ITSYBITSY_M4_EXPRESS
This commit is contained in:
Andrew Leech
2022-08-10 14:13:17 +10:00
committed by Damien George
parent 82b3500724
commit f7f56d4285
11 changed files with 225 additions and 109 deletions

View File

@@ -27,6 +27,7 @@
#define MICROPY_INCLUDED_PY_OBJSTR_H
#include "py/obj.h"
#include "py/objarray.h"
typedef struct _mp_obj_str_t {
mp_obj_base_t base;
@@ -36,6 +37,13 @@ typedef struct _mp_obj_str_t {
const byte *data;
} mp_obj_str_t;
// This static assert is used to ensure that mp_obj_str_t and mp_obj_array_t are compatible,
// meaning that their len and data/items entries are at the same offsets in the struct.
// This allows the same code to be used for str/bytes and bytearray.
#define MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE \
MP_STATIC_ASSERT(offsetof(mp_obj_str_t, len) == offsetof(mp_obj_array_t, len) \
&& offsetof(mp_obj_str_t, data) == offsetof(mp_obj_array_t, items))
#define MP_DEFINE_STR_OBJ(obj_name, str) mp_obj_str_t obj_name = {{&mp_type_str}, 0, sizeof(str) - 1, (const byte *)str}
// use this macro to extract the string hash
@@ -70,6 +78,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len);
if (mp_obj_is_qstr(str_obj_in)) { \
str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); \
} else { \
MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE; \
str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; \
str_data = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->data; \
}
@@ -118,4 +127,14 @@ MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj);
MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj);
extern const mp_obj_dict_t mp_obj_str_locals_dict;
#if MICROPY_PY_BUILTINS_BYTEARRAY
extern const mp_obj_dict_t mp_obj_bytearray_locals_dict;
#endif
#if MICROPY_PY_ARRAY
extern const mp_obj_dict_t mp_obj_array_locals_dict;
#endif
#endif // MICROPY_INCLUDED_PY_OBJSTR_H