py/dynruntime: Make malloc functions raise MemoryError on failure.

Addresses some TODOs in this file.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George
2025-03-18 10:24:58 +11:00
parent 994751c251
commit fdc0c6f8f6

View File

@@ -28,6 +28,14 @@
// This header file contains definitions to dynamically implement the static
// MicroPython runtime API defined in py/obj.h and py/runtime.h.
//
// All of the symbols made available in this header are overriding those defined
// in py/obj.h and py/runtime.h. This is done with macros. For macros that
// would be too complicated (usually more than a single expression), they call a
// static-inline function for the implementation. This function has the same
// name as the macro (hence the same name as a public API function) but with
// "_dyn" appended. For example, the m_malloc() macro calls the m_malloc_dyn()
// static-inline function.
#include "py/binary.h"
#include "py/nativeglue.h"
@@ -39,6 +47,10 @@
#error "dynruntime.h included in non-dynamic-module build."
#endif
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
#error "MICROPY_MALLOC_USES_ALLOCATED_SIZE must be disable in a dynamic-module build."
#endif
#undef MP_ROM_QSTR
#undef MP_OBJ_QSTR_VALUE
#undef MP_OBJ_NEW_QSTR
@@ -52,13 +64,32 @@
/******************************************************************************/
// Memory allocation
#define m_malloc_fail(num_bytes) (m_malloc_fail_dyn((num_bytes)))
#define m_malloc(n) (m_malloc_dyn((n)))
#define m_free(ptr) (m_free_dyn((ptr)))
#define m_realloc(ptr, new_num_bytes) (m_realloc_dyn((ptr), (new_num_bytes)))
#define m_realloc_maybe(ptr, new_num_bytes, allow_move) (m_realloc_maybe_dyn((ptr), (new_num_bytes), (allow_move)))
static NORETURN inline void m_malloc_fail_dyn(size_t num_bytes) {
mp_fun_table.raise_msg(
mp_fun_table.load_global(MP_QSTR_MemoryError),
"memory allocation failed");
}
static inline void *m_realloc_maybe_dyn(void *ptr, size_t new_num_bytes, bool allow_move) {
return mp_fun_table.realloc_(ptr, new_num_bytes, allow_move);
}
static inline void *m_realloc_checked_dyn(void *ptr, size_t new_num_bytes, bool allow_move) {
ptr = m_realloc_maybe(ptr, new_num_bytes, allow_move);
if (ptr == NULL && new_num_bytes != 0) {
m_malloc_fail(new_num_bytes);
}
return ptr;
}
static inline void *m_malloc_dyn(size_t n) {
// TODO won't raise on OOM
return mp_fun_table.realloc_(NULL, n, false);
return m_realloc_checked_dyn(NULL, n, false);
}
static inline void m_free_dyn(void *ptr) {
@@ -66,8 +97,7 @@ static inline void m_free_dyn(void *ptr) {
}
static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) {
// TODO won't raise on OOM
return mp_fun_table.realloc_(ptr, new_num_bytes, true);
return m_realloc_checked_dyn(ptr, new_num_bytes, true);
}
/******************************************************************************/