From e6c6fe3275ba8d405e566548a277fa7eaea416b9 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 28 Mar 2015 01:14:45 +0200 Subject: [PATCH] runtime: Split mp_call_prepare_args_n_kw_var() from mp_call_method_n_kw_var(). Allow for reuse for stackless design, where preparing args is separate from calling. --- py/runtime.c | 17 ++++++++++++++--- py/runtime.h | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/py/runtime.c b/py/runtime.c index 0ff78b2a96..f6bc7aa846 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -577,7 +577,7 @@ mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *a return mp_call_function_n_kw(args[0], n_args + adjust, n_kw, args + 2 - adjust); } -mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args) { +void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args, call_args_t *out_args) { mp_obj_t fun = *args++; mp_obj_t self = MP_OBJ_NULL; if (have_self) { @@ -715,8 +715,19 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp } } - mp_obj_t res = mp_call_function_n_kw(fun, pos_args_len, (args2_len - pos_args_len) / 2, args2); - m_del(mp_obj_t, args2, args2_alloc); + out_args->fun = fun; + out_args->args = args2; + out_args->n_args = pos_args_len; + out_args->n_kw = (args2_len - pos_args_len) / 2; + out_args->n_alloc = args2_alloc; +} + +mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args) { + call_args_t out_args; + mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args); + + mp_obj_t res = mp_call_function_n_kw(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); return res; } diff --git a/py/runtime.h b/py/runtime.h index bead02831a..8666ce1075 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -97,6 +97,17 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun, mp_uint_t n_args, mp_uint_t n_kw, c mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args); +typedef struct _call_args_t { + mp_obj_t fun; + mp_uint_t n_args, n_kw, n_alloc; + mp_obj_t *args; +} call_args_t; + +// Takes arguments which are the most general mix of Python arg types, and +// prepares argument array suitable for passing to ->call() method of a +// function object (and mp_call_function_n_kw()). +void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args, call_args_t *out_args); + void mp_unpack_sequence(mp_obj_t seq, mp_uint_t num, mp_obj_t *items); void mp_unpack_ex(mp_obj_t seq, mp_uint_t num, mp_obj_t *items); mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value);