py/misc: Change sizeof to offsetof for variable-length alloc.

This fixes the case where e.g.

    struct foo_t {
      mp_obj_t x;
      uint16_t y;
      char buf[];
    };

will have `sizeof(struct foo_t)==8`, but `offsetof(struct foo_t, buf)==6`.

When computing the size to allocate for `m_new_obj_var` we need to use
offsetof to avoid over-allocating. This is important especially when it
might cause it to spill over into another GC block.

This work was funded through GitHub Sponsors.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared
2023-11-03 14:19:55 +11:00
committed by Damien George
parent c85db05244
commit b6a9778484
11 changed files with 24 additions and 24 deletions

View File

@@ -215,7 +215,7 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
// RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
// return NULL, then vm.c takes the needed action (either raise
// RuntimeError or fallback to stack allocation).
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
code_state = m_new_obj_var_maybe(mp_code_state_t, state, byte, state_size);
if (!code_state) {
return NULL;
}
@@ -247,10 +247,10 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
// allocate state for locals and stack
mp_code_state_t *code_state = NULL;
#if MICROPY_ENABLE_PYSTACK
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
code_state = mp_pystack_alloc(offsetof(mp_code_state_t, state) + state_size);
#else
if (state_size > VM_MAX_STATE_ON_STACK) {
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
code_state = m_new_obj_var_maybe(mp_code_state_t, state, byte, state_size);
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
if (code_state != NULL) {
memset(code_state->state, 0, state_size);
@@ -258,7 +258,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
#endif
}
if (code_state == NULL) {
code_state = alloca(sizeof(mp_code_state_t) + state_size);
code_state = alloca(offsetof(mp_code_state_t, state) + state_size);
#if MICROPY_DEBUG_VM_STACK_OVERFLOW
memset(code_state->state, 0, state_size);
#endif
@@ -320,7 +320,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
#else
// free the state if it was allocated on the heap
if (state_size != 0) {
m_del_var(mp_code_state_t, byte, state_size, code_state);
m_del_var(mp_code_state_t, state, byte, state_size, code_state);
}
#endif