summaryrefslogtreecommitdiff
path: root/py/vm.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-11-26 23:48:23 +1100
committerDamien George <damien.p.george@gmail.com>2017-12-11 13:49:09 +1100
commit30fd8484ebe41faad467fbc8dd4a6f72250f203c (patch)
tree623db9780a7c92dc66979f7a48a7e15cc4752c37 /py/vm.c
parent971699abe7c9ac07c3059cbbc452043e35eb6200 (diff)
py/runtime: Use the Python stack when building *arg and **kwarg state.
With MICROPY_ENABLE_PYSTACK enabled the following language constructs no longer allocate on the heap: f(*arg), f(**kwarg).
Diffstat (limited to 'py/vm.c')
-rw-r--r--py/vm.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/py/vm.c b/py/vm.c
index a8a73f323..b18a2b5e3 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -966,7 +966,11 @@ unwind_jump:;
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
out_args.n_args, out_args.n_kw, out_args.args);
- m_del(mp_obj_t, out_args.args, out_args.n_alloc);
+ #if !MICROPY_ENABLE_PYSTACK
+ // Freeing args at this point does not follow a LIFO order so only do it if
+ // pystack is not enabled. For pystack, they are freed when code_state is.
+ mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
+ #endif
if (new_state) {
new_state->prev = code_state;
code_state = new_state;
@@ -1043,7 +1047,11 @@ unwind_jump:;
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
out_args.n_args, out_args.n_kw, out_args.args);
- m_del(mp_obj_t, out_args.args, out_args.n_alloc);
+ #if !MICROPY_ENABLE_PYSTACK
+ // Freeing args at this point does not follow a LIFO order so only do it if
+ // pystack is not enabled. For pystack, they are freed when code_state is.
+ mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
+ #endif
if (new_state) {
new_state->prev = code_state;
code_state = new_state;
@@ -1110,6 +1118,8 @@ unwind_return:
mp_globals_set(code_state->old_globals);
mp_code_state_t *new_code_state = code_state->prev;
#if MICROPY_ENABLE_PYSTACK
+ // Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
+ // (The latter is implicitly freed when using pystack due to its LIFO nature.)
// 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));
@@ -1458,6 +1468,8 @@ unwind_loop:
mp_globals_set(code_state->old_globals);
mp_code_state_t *new_code_state = code_state->prev;
#if MICROPY_ENABLE_PYSTACK
+ // Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
+ // (The latter is implicitly freed when using pystack due to its LIFO nature.)
// 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));