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.
This commit is contained in:
Paul Sokolovsky 2015-03-28 01:14:45 +02:00
parent 390e92688c
commit e6c6fe3275
2 changed files with 25 additions and 3 deletions

View File

@ -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); 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 fun = *args++;
mp_obj_t self = MP_OBJ_NULL; mp_obj_t self = MP_OBJ_NULL;
if (have_self) { 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); out_args->fun = fun;
m_del(mp_obj_t, args2, args2_alloc); 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; return res;
} }

View File

@ -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(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); 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_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); 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); mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value);