Skip to content

Commit 1e5a33d

Browse files
committed
py: Convert all uses of alloca() to use new scoped allocation API.
1 parent 02d830c commit 1e5a33d

6 files changed

Lines changed: 41 additions & 6 deletions

File tree

py/builtinimport.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,17 +318,18 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
318318
}
319319

320320
uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
321-
char *new_mod = alloca(new_mod_l);
321+
char *new_mod = mp_local_alloc(new_mod_l);
322322
memcpy(new_mod, this_name, p - this_name);
323323
if (mod_len != 0) {
324324
new_mod[p - this_name] = '.';
325325
memcpy(new_mod + (p - this_name) + 1, mod_str, mod_len);
326326
}
327327

328328
qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l);
329+
mp_local_free(new_mod);
329330
DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
330331
module_name = MP_OBJ_NEW_QSTR(new_mod_q);
331-
mod_str = new_mod;
332+
mod_str = qstr_str(new_mod_q);
332333
mod_len = new_mod_l;
333334
}
334335

py/compile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
10501050
for (int i = 0; i < n; i++) {
10511051
len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
10521052
}
1053-
char *q_ptr = alloca(len);
1053+
char *q_ptr = mp_local_alloc(len);
10541054
char *str_dest = q_ptr;
10551055
for (int i = 0; i < n; i++) {
10561056
if (i > 0) {
@@ -1062,6 +1062,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
10621062
str_dest += str_src_len;
10631063
}
10641064
qstr q_full = qstr_from_strn(q_ptr, len);
1065+
mp_local_free(q_ptr);
10651066
EMIT_ARG(import_name, q_full);
10661067
if (is_as) {
10671068
for (int i = 1; i < n; i++) {

py/objboundmeth.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5151
// need to insert self before all other args and then call meth
5252
size_t n_total = n_args + 2 * n_kw;
5353
mp_obj_t *args2 = NULL;
54+
#if MICROPY_ENABLE_PYSTACK
55+
args2 = mp_pystack_alloc(sizeof(mp_obj_t) * (1 + n_total));
56+
#else
5457
mp_obj_t *free_args2 = NULL;
5558
if (n_total > 4) {
5659
// 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
6164
// (fallback to) use stack to allocate temporary args array
6265
args2 = alloca(sizeof(mp_obj_t) * (1 + n_total));
6366
}
67+
#endif
6468
args2[0] = self;
6569
memcpy(args2 + 1, args, n_total * sizeof(mp_obj_t));
6670
mp_obj_t res = mp_call_function_n_kw(meth, n_args + 1, n_kw, args2);
71+
#if MICROPY_ENABLE_PYSTACK
72+
mp_pystack_free(args2);
73+
#else
6774
if (free_args2 != NULL) {
6875
m_del(mp_obj_t, free_args2, 1 + n_total);
6976
}
77+
#endif
7078
return res;
7179
}
7280

py/objfun.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
225225
DECODE_CODESTATE_SIZE(self->bytecode, n_state, state_size);
226226

227227
mp_code_state_t *code_state;
228+
#if MICROPY_ENABLE_PYSTACK
229+
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
230+
#else
228231
// If we use m_new_obj_var(), then on no memory, MemoryError will be
229232
// raised. But this is not correct exception for a function call,
230233
// 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
234237
if (!code_state) {
235238
return NULL;
236239
}
240+
#endif
237241

238242
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
239243

@@ -260,13 +264,17 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
260264

261265
// allocate state for locals and stack
262266
mp_code_state_t *code_state = NULL;
267+
#if MICROPY_ENABLE_PYSTACK
268+
code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
269+
#else
263270
if (state_size > VM_MAX_STATE_ON_STACK) {
264271
code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
265272
}
266273
if (code_state == NULL) {
267274
code_state = alloca(sizeof(mp_code_state_t) + state_size);
268275
state_size = 0; // indicate that we allocated using alloca
269276
}
277+
#endif
270278

271279
INIT_CODESTATE(code_state, self, n_args, n_kw, args);
272280

@@ -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
312320
result = code_state->state[n_state - 1];
313321
}
314322

323+
#if MICROPY_ENABLE_PYSTACK
324+
mp_pystack_free(code_state);
325+
#else
315326
// free the state if it was allocated on the heap
316327
if (state_size != 0) {
317328
m_del_var(mp_code_state_t, byte, state_size, code_state);
318329
}
330+
#endif
319331

320332
if (vm_return_kind == MP_VM_RETURN_NORMAL) {
321333
return result;

py/runtime.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1348,11 +1348,12 @@ mp_obj_t mp_import_from(mp_obj_t module, qstr name) {
13481348
const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
13491349

13501350
const uint dot_name_len = pkg_name_len + 1 + qstr_len(name);
1351-
char *dot_name = alloca(dot_name_len);
1351+
char *dot_name = mp_local_alloc(dot_name_len);
13521352
memcpy(dot_name, pkg_name, pkg_name_len);
13531353
dot_name[pkg_name_len] = '.';
13541354
memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
13551355
qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
1356+
mp_local_free(dot_name);
13561357

13571358
mp_obj_t args[5];
13581359
args[0] = MP_OBJ_NEW_QSTR(dot_name_q);

py/vm.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,13 @@ unwind_jump:;
11081108
if (code_state->prev != NULL) {
11091109
mp_obj_t res = *sp;
11101110
mp_globals_set(code_state->old_globals);
1111-
code_state = code_state->prev;
1111+
mp_code_state_t *new_code_state = code_state->prev;
1112+
#if MICROPY_ENABLE_PYSTACK
1113+
// The sizeof in the following statement does not include the size of the variable
1114+
// part of the struct. This arg is anyway not used if pystack is enabled.
1115+
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
1116+
#endif
1117+
code_state = new_code_state;
11121118
*code_state->sp = res;
11131119
goto run_code_state;
11141120
}
@@ -1450,7 +1456,13 @@ unwind_jump:;
14501456
#if MICROPY_STACKLESS
14511457
} else if (code_state->prev != NULL) {
14521458
mp_globals_set(code_state->old_globals);
1453-
code_state = code_state->prev;
1459+
mp_code_state_t *new_code_state = code_state->prev;
1460+
#if MICROPY_ENABLE_PYSTACK
1461+
// The sizeof in the following statement does not include the size of the variable
1462+
// part of the struct. This arg is anyway not used if pystack is enabled.
1463+
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
1464+
#endif
1465+
code_state = new_code_state;
14541466
size_t n_state = mp_decode_uint_value(code_state->fun_bc->bytecode);
14551467
fastn = &code_state->state[n_state - 1];
14561468
exc_stack = (mp_exc_stack_t*)(code_state->state + n_state);

0 commit comments

Comments
 (0)