py: Convert all uses of alloca() to use new scoped allocation API.
This commit is contained in:
parent
02d830c035
commit
1e5a33df41
|
@ -318,7 +318,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
|
|||
}
|
||||
|
||||
uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
|
||||
char *new_mod = alloca(new_mod_l);
|
||||
char *new_mod = mp_local_alloc(new_mod_l);
|
||||
memcpy(new_mod, this_name, p - this_name);
|
||||
if (mod_len != 0) {
|
||||
new_mod[p - this_name] = '.';
|
||||
|
@ -326,9 +326,10 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
|
|||
}
|
||||
|
||||
qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l);
|
||||
mp_local_free(new_mod);
|
||||
DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
|
||||
module_name = MP_OBJ_NEW_QSTR(new_mod_q);
|
||||
mod_str = new_mod;
|
||||
mod_str = qstr_str(new_mod_q);
|
||||
mod_len = new_mod_l;
|
||||
}
|
||||
|
||||
|
|
|
@ -1050,7 +1050,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
|
|||
for (int i = 0; i < n; i++) {
|
||||
len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
}
|
||||
char *q_ptr = alloca(len);
|
||||
char *q_ptr = mp_local_alloc(len);
|
||||
char *str_dest = q_ptr;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) {
|
||||
|
@ -1062,6 +1062,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
|
|||
str_dest += str_src_len;
|
||||
}
|
||||
qstr q_full = qstr_from_strn(q_ptr, len);
|
||||
mp_local_free(q_ptr);
|
||||
EMIT_ARG(import_name, q_full);
|
||||
if (is_as) {
|
||||
for (int i = 1; i < n; i++) {
|
||||
|
|
|
@ -51,6 +51,9 @@ mp_obj_t mp_call_method_self_n_kw(mp_obj_t meth, mp_obj_t self, size_t n_args, s
|
|||
// need to insert self before all other args and then call meth
|
||||
size_t n_total = n_args + 2 * n_kw;
|
||||
mp_obj_t *args2 = NULL;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
args2 = mp_pystack_alloc(sizeof(mp_obj_t) * (1 + n_total));
|
||||
#else
|
||||
mp_obj_t *free_args2 = NULL;
|
||||
if (n_total > 4) {
|
||||
// try to use heap to allocate temporary args array
|
||||
|
@ -61,12 +64,17 @@ mp_obj_t mp_call_method_self_n_kw(mp_obj_t meth, mp_obj_t self, size_t n_args, s
|
|||
// (fallback to) use stack to allocate temporary args array
|
||||
args2 = alloca(sizeof(mp_obj_t) * (1 + n_total));
|
||||
}
|
||||
#endif
|
||||
args2[0] = self;
|
||||
memcpy(args2 + 1, args, n_total * sizeof(mp_obj_t));
|
||||
mp_obj_t res = mp_call_function_n_kw(meth, n_args + 1, n_kw, args2);
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
mp_pystack_free(args2);
|
||||
#else
|
||||
if (free_args2 != NULL) {
|
||||
m_del(mp_obj_t, free_args2, 1 + n_total);
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
12
py/objfun.c
12
py/objfun.c
|
@ -225,6 +225,9 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
|
|||
DECODE_CODESTATE_SIZE(self->bytecode, n_state, state_size);
|
||||
|
||||
mp_code_state_t *code_state;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
|
||||
#else
|
||||
// If we use m_new_obj_var(), then on no memory, MemoryError will be
|
||||
// raised. But this is not correct exception for a function call,
|
||||
// RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
|
||||
|
@ -234,6 +237,7 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
|
|||
if (!code_state) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
|
||||
|
||||
|
@ -260,6 +264,9 @@ 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);
|
||||
#else
|
||||
if (state_size > VM_MAX_STATE_ON_STACK) {
|
||||
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
|
||||
}
|
||||
|
@ -267,6 +274,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
|||
code_state = alloca(sizeof(mp_code_state_t) + state_size);
|
||||
state_size = 0; // indicate that we allocated using alloca
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
|
||||
|
||||
|
@ -312,10 +320,14 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
|||
result = code_state->state[n_state - 1];
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
mp_pystack_free(code_state);
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
|
||||
return result;
|
||||
|
|
|
@ -1348,11 +1348,12 @@ import_error:
|
|||
const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
|
||||
|
||||
const uint dot_name_len = pkg_name_len + 1 + qstr_len(name);
|
||||
char *dot_name = alloca(dot_name_len);
|
||||
char *dot_name = mp_local_alloc(dot_name_len);
|
||||
memcpy(dot_name, pkg_name, pkg_name_len);
|
||||
dot_name[pkg_name_len] = '.';
|
||||
memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
|
||||
qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
|
||||
mp_local_free(dot_name);
|
||||
|
||||
mp_obj_t args[5];
|
||||
args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
|
||||
|
|
16
py/vm.c
16
py/vm.c
|
@ -1108,7 +1108,13 @@ unwind_return:
|
|||
if (code_state->prev != NULL) {
|
||||
mp_obj_t res = *sp;
|
||||
mp_globals_set(code_state->old_globals);
|
||||
code_state = code_state->prev;
|
||||
mp_code_state_t *new_code_state = code_state->prev;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
// The sizeof in the following statement does not include the size of the variable
|
||||
// part of the struct. This arg is anyway not used if pystack is enabled.
|
||||
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
|
||||
#endif
|
||||
code_state = new_code_state;
|
||||
*code_state->sp = res;
|
||||
goto run_code_state;
|
||||
}
|
||||
|
@ -1450,7 +1456,13 @@ unwind_loop:
|
|||
#if MICROPY_STACKLESS
|
||||
} else if (code_state->prev != NULL) {
|
||||
mp_globals_set(code_state->old_globals);
|
||||
code_state = code_state->prev;
|
||||
mp_code_state_t *new_code_state = code_state->prev;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
// The sizeof in the following statement does not include the size of the variable
|
||||
// part of the struct. This arg is anyway not used if pystack is enabled.
|
||||
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
|
||||
#endif
|
||||
code_state = new_code_state;
|
||||
size_t n_state = mp_decode_uint_value(code_state->fun_bc->bytecode);
|
||||
fastn = &code_state->state[n_state - 1];
|
||||
exc_stack = (mp_exc_stack_t*)(code_state->state + n_state);
|
||||
|
|
Loading…
Reference in New Issue