core: Add MP_BUFFER_GET_BASE
This flag requests that the filled bufinfo give the associated GC base address, for classes like memoryview & uctypes that need it in order to ensure liveness of the data they refer to. I had initially hoped that this would be a forward compatible change, but the practice of checking `flags == MP_BUFFER_READ` means it's not, so I might as well make it unconditional. But, here, it's an intermediate step that passed the tests.
This commit is contained in:
parent
a06e973ddc
commit
6d16c8d3fe
9 changed files with 18 additions and 7 deletions
|
|
@ -82,7 +82,7 @@ mp_obj_t mp_vfs_rom_file_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_
|
|||
|
||||
static mp_int_t vfs_rom_file_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
mp_obj_vfs_rom_file_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (flags == MP_BUFFER_READ) {
|
||||
if ((flags & MP_BUFFER_RW) == MP_BUFFER_READ) {
|
||||
bufinfo->buf = (void *)self->file_data;
|
||||
bufinfo->len = self->file_size;
|
||||
bufinfo->typecode = 'B';
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static mp_obj_t alif_flash_make_new(const mp_obj_type_t *type, size_t n_args, si
|
|||
|
||||
static mp_int_t alif_flash_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
alif_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (flags == MP_BUFFER_READ) {
|
||||
if ((flags & MP_BUFFER_RW) == MP_BUFFER_READ) {
|
||||
bufinfo->buf = (void *)(ospi_flash_get_xip_base() + self->flash_base_addr);
|
||||
bufinfo->len = self->flash_size;
|
||||
bufinfo->typecode = 'B';
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ static mp_obj_t esp32_partition_make_new(const mp_obj_type_t *type, size_t n_arg
|
|||
#if MICROPY_VFS_ROM_IOCTL
|
||||
static mp_int_t esp32_partition_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
esp32_partition_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self == &esp32_partition_romfs_obj && flags == MP_BUFFER_READ) {
|
||||
if (self == &esp32_partition_romfs_obj && (flags & MP_BUFFER_RW) == MP_BUFFER_READ) {
|
||||
if (esp32_partition_romfs_ptr == NULL) {
|
||||
check_esp_err(esp_partition_mmap(self->part, 0, self->part->size, ESP_PARTITION_MMAP_DATA, &esp32_partition_romfs_ptr, &esp32_partition_romfs_handle));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ static mp_obj_t rp2_flash_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||
|
||||
static mp_int_t rp2_flash_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
rp2_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (flags == MP_BUFFER_READ) {
|
||||
if ((flags & MP_BUFFER_RW) == MP_BUFFER_READ) {
|
||||
bufinfo->buf = (void *)(XIP_BASE + self->flash_base);
|
||||
bufinfo->len = self->flash_size;
|
||||
bufinfo->typecode = 'B';
|
||||
|
|
|
|||
8
py/obj.c
8
py/obj.c
|
|
@ -586,8 +586,14 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity);
|
|||
|
||||
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
const mp_obj_type_t *type = mp_obj_get_type(obj);
|
||||
if (flags & MP_BUFFER_GET_BASE) {
|
||||
bufinfo->base = NULL;
|
||||
}
|
||||
if (MP_OBJ_TYPE_HAS_SLOT(type, buffer)
|
||||
&& MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags & MP_BUFFER_RW) == 0) {
|
||||
&& MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags & ~MP_BUFFER_RAISE_IF_UNSUPPORTED) == 0) {
|
||||
if ((flags & MP_BUFFER_GET_BASE) && !bufinfo->base) {
|
||||
bufinfo->base = bufinfo->buf;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (flags & MP_BUFFER_RAISE_IF_UNSUPPORTED) {
|
||||
|
|
|
|||
2
py/obj.h
2
py/obj.h
|
|
@ -608,12 +608,14 @@ typedef struct _mp_buffer_info_t {
|
|||
void *buf; // can be NULL if len == 0
|
||||
size_t len; // in bytes
|
||||
int typecode; // as per binary.h
|
||||
void *base; // the "base address" of the buffer, only populated if MP_BUFFER_GET_BASE flag is set and the type supports it.
|
||||
} mp_buffer_info_t;
|
||||
|
||||
#define MP_BUFFER_READ (1)
|
||||
#define MP_BUFFER_WRITE (2)
|
||||
#define MP_BUFFER_RW (MP_BUFFER_READ | MP_BUFFER_WRITE)
|
||||
#define MP_BUFFER_RAISE_IF_UNSUPPORTED (4)
|
||||
#define MP_BUFFER_GET_BASE (8) // populate the "base" pointer
|
||||
|
||||
typedef mp_int_t (*mp_buffer_fun_t)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -599,6 +599,9 @@ static mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui
|
|||
return 1;
|
||||
}
|
||||
bufinfo->buf = (uint8_t *)bufinfo->buf + (size_t)o->memview_offset * sz;
|
||||
if (flags & MP_BUFFER_GET_BASE) {
|
||||
bufinfo->base = (uint8_t *)o->items;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ typedef struct _micropython_ringio_obj_t {
|
|||
static mp_obj_t micropython_ringio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
mp_int_t buff_size = -1;
|
||||
mp_buffer_info_t bufinfo = {NULL, 0, 0};
|
||||
mp_buffer_info_t bufinfo = {NULL, 0, 0, 0};
|
||||
|
||||
if (!mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) {
|
||||
buff_size = mp_obj_get_int(args[0]);
|
||||
|
|
|
|||
|
|
@ -2060,7 +2060,7 @@ static MP_DEFINE_CONST_CLASSMETHOD_OBJ(bytes_fromhex_classmethod_obj, MP_ROM_PTR
|
|||
#endif // MICROPY_PY_BUILTINS_BYTES_HEX
|
||||
|
||||
mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
||||
if (flags == MP_BUFFER_READ) {
|
||||
if ((flags & MP_BUFFER_RW) == MP_BUFFER_READ) {
|
||||
GET_STR_DATA_LEN(self_in, str_data, str_len);
|
||||
bufinfo->buf = (void *)str_data;
|
||||
bufinfo->len = str_len;
|
||||
|
|
|
|||
Loading…
Reference in a new issue