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);
|
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);
|
memcpy(new_mod, this_name, p - this_name);
|
||||||
if (mod_len != 0) {
|
if (mod_len != 0) {
|
||||||
new_mod[p - this_name] = '.';
|
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);
|
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));
|
DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
|
||||||
module_name = MP_OBJ_NEW_QSTR(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;
|
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++) {
|
for (int i = 0; i < n; i++) {
|
||||||
len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[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;
|
char *str_dest = q_ptr;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
if (i > 0) {
|
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;
|
str_dest += str_src_len;
|
||||||
}
|
}
|
||||||
qstr q_full = qstr_from_strn(q_ptr, len);
|
qstr q_full = qstr_from_strn(q_ptr, len);
|
||||||
|
mp_local_free(q_ptr);
|
||||||
EMIT_ARG(import_name, q_full);
|
EMIT_ARG(import_name, q_full);
|
||||||
if (is_as) {
|
if (is_as) {
|
||||||
for (int i = 1; i < n; i++) {
|
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
|
// need to insert self before all other args and then call meth
|
||||||
size_t n_total = n_args + 2 * n_kw;
|
size_t n_total = n_args + 2 * n_kw;
|
||||||
mp_obj_t *args2 = NULL;
|
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;
|
mp_obj_t *free_args2 = NULL;
|
||||||
if (n_total > 4) {
|
if (n_total > 4) {
|
||||||
// try to use heap to allocate temporary args array
|
// 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
|
// (fallback to) use stack to allocate temporary args array
|
||||||
args2 = alloca(sizeof(mp_obj_t) * (1 + n_total));
|
args2 = alloca(sizeof(mp_obj_t) * (1 + n_total));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
args2[0] = self;
|
args2[0] = self;
|
||||||
memcpy(args2 + 1, args, n_total * sizeof(mp_obj_t));
|
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);
|
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) {
|
if (free_args2 != NULL) {
|
||||||
m_del(mp_obj_t, free_args2, 1 + n_total);
|
m_del(mp_obj_t, free_args2, 1 + n_total);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return res;
|
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);
|
DECODE_CODESTATE_SIZE(self->bytecode, n_state, state_size);
|
||||||
|
|
||||||
mp_code_state_t *code_state;
|
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
|
// 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,
|
// raised. But this is not correct exception for a function call,
|
||||||
// RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
|
// 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) {
|
if (!code_state) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
|
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
|
// allocate state for locals and stack
|
||||||
mp_code_state_t *code_state = NULL;
|
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) {
|
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, 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);
|
code_state = alloca(sizeof(mp_code_state_t) + state_size);
|
||||||
state_size = 0; // indicate that we allocated using alloca
|
state_size = 0; // indicate that we allocated using alloca
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
|
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];
|
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
|
// free the state if it was allocated on the heap
|
||||||
if (state_size != 0) {
|
if (state_size != 0) {
|
||||||
m_del_var(mp_code_state_t, byte, state_size, code_state);
|
m_del_var(mp_code_state_t, byte, state_size, code_state);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
|
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -1348,11 +1348,12 @@ import_error:
|
|||||||
const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
|
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);
|
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);
|
memcpy(dot_name, pkg_name, pkg_name_len);
|
||||||
dot_name[pkg_name_len] = '.';
|
dot_name[pkg_name_len] = '.';
|
||||||
memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
|
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);
|
qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
|
||||||
|
mp_local_free(dot_name);
|
||||||
|
|
||||||
mp_obj_t args[5];
|
mp_obj_t args[5];
|
||||||
args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
|
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) {
|
if (code_state->prev != NULL) {
|
||||||
mp_obj_t res = *sp;
|
mp_obj_t res = *sp;
|
||||||
mp_globals_set(code_state->old_globals);
|
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;
|
*code_state->sp = res;
|
||||||
goto run_code_state;
|
goto run_code_state;
|
||||||
}
|
}
|
||||||
@ -1450,7 +1456,13 @@ unwind_loop:
|
|||||||
#if MICROPY_STACKLESS
|
#if MICROPY_STACKLESS
|
||||||
} else if (code_state->prev != NULL) {
|
} else if (code_state->prev != NULL) {
|
||||||
mp_globals_set(code_state->old_globals);
|
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);
|
size_t n_state = mp_decode_uint_value(code_state->fun_bc->bytecode);
|
||||||
fastn = &code_state->state[n_state - 1];
|
fastn = &code_state->state[n_state - 1];
|
||||||
exc_stack = (mp_exc_stack_t*)(code_state->state + n_state);
|
exc_stack = (mp_exc_stack_t*)(code_state->state + n_state);
|
||||||
|
Loading…
Reference in New Issue
Block a user