diff options
author | Damien George <damien.p.george@gmail.com> | 2015-04-06 22:48:21 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-04-06 22:48:21 +0100 |
commit | 78772ada0ddc9222c0338f94a42e33e10bb24b55 (patch) | |
tree | 2305c4f09f897c5032102b2f8c0f0b3720afb98f /py | |
parent | 282ca09f8e386f24e1e87acd3de93954b6a8035c (diff) | |
download | micropython-78772ada0ddc9222c0338f94a42e33e10bb24b55.tar.gz micropython-78772ada0ddc9222c0338f94a42e33e10bb24b55.zip |
py: Implement calling functions with *args in native emitter.
Diffstat (limited to 'py')
-rw-r--r-- | py/emitnative.c | 53 | ||||
-rw-r--r-- | py/nativeglue.c | 1 | ||||
-rw-r--r-- | py/runtime0.h | 1 |
3 files changed, 42 insertions, 13 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index b0ad3f04f3..f72112ba07 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -184,6 +184,7 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { [MP_F_MAKE_FUNCTION_FROM_RAW_CODE] = 3, [MP_F_NATIVE_CALL_FUNCTION_N_KW] = 3, [MP_F_CALL_METHOD_N_KW] = 3, + [MP_F_CALL_METHOD_N_KW_VAR] = 3, [MP_F_GETITER] = 1, [MP_F_ITERNEXT] = 1, [MP_F_NLR_PUSH] = 1, @@ -2189,13 +2190,12 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u // TODO: in viper mode, call special runtime routine with type info for args, // and wanted type info for return, to remove need for boxing/unboxing - assert(!star_flags); - emit_native_pre(emit); vtype_kind_t vtype_fun = peek_vtype(emit, n_positional + 2 * n_keyword); if (vtype_fun == VTYPE_BUILTIN_CAST) { // casting operator assert(n_positional == 1 && n_keyword == 0); + assert(!star_flags); DEBUG_printf(" cast to %d\n", vtype_fun); vtype_kind_t vtype_cast = peek_stack(emit, 1)->data.u_imm; switch (peek_vtype(emit, 0)) { @@ -2221,22 +2221,49 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u assert(!"TODO: convert obj to int"); } } else { - if (n_positional != 0 || n_keyword != 0) { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword); // pointer to args - } - emit_pre_pop_reg(emit, &vtype_fun, REG_ARG_1); // the function assert(vtype_fun == VTYPE_PYOBJ); - emit_call_with_imm_arg(emit, MP_F_NATIVE_CALL_FUNCTION_N_KW, n_positional | (n_keyword << 8), REG_ARG_2); - emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + if (star_flags) { + if (!(star_flags & MP_EMIT_STAR_FLAG_SINGLE)) { + // load dummy entry for non-existent pos_seq + emit_native_load_null(emit); + emit_native_rot_two(emit); + } else if (!(star_flags & MP_EMIT_STAR_FLAG_DOUBLE)) { + // load dummy entry for non-existent kw_dict + emit_native_load_null(emit); + } + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 3); // pointer to args + emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 0, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + } else { + if (n_positional != 0 || n_keyword != 0) { + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword); // pointer to args + } + emit_pre_pop_reg(emit, &vtype_fun, REG_ARG_1); // the function + emit_call_with_imm_arg(emit, MP_F_NATIVE_CALL_FUNCTION_N_KW, n_positional | (n_keyword << 8), REG_ARG_2); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + } } } STATIC void emit_native_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) { - assert(!star_flags); - emit_native_pre(emit); - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2 + n_positional + 2 * n_keyword); // pointer to items, including meth and self - emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, n_positional, REG_ARG_1, n_keyword, REG_ARG_2); - emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + if (star_flags) { + if (!(star_flags & MP_EMIT_STAR_FLAG_SINGLE)) { + // load dummy entry for non-existent pos_seq + emit_native_load_null(emit); + emit_native_rot_two(emit); + } else if (!(star_flags & MP_EMIT_STAR_FLAG_DOUBLE)) { + // load dummy entry for non-existent kw_dict + emit_native_load_null(emit); + } + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 4); // pointer to args + emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 1, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + } else { + emit_native_pre(emit); + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2 + n_positional + 2 * n_keyword); // pointer to items, including meth and self + emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, n_positional, REG_ARG_1, n_keyword, REG_ARG_2); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + } } STATIC void emit_native_return_value(emit_t *emit) { diff --git a/py/nativeglue.c b/py/nativeglue.c index 674ee99d6a..ab4063014c 100644 --- a/py/nativeglue.c +++ b/py/nativeglue.c @@ -117,6 +117,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_make_function_from_raw_code, mp_native_call_function_n_kw, mp_call_method_n_kw, + mp_call_method_n_kw_var, mp_getiter, mp_iternext, nlr_push, diff --git a/py/runtime0.h b/py/runtime0.h index 6fddace357..7ee8c9aa49 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -133,6 +133,7 @@ typedef enum { MP_F_MAKE_FUNCTION_FROM_RAW_CODE, MP_F_NATIVE_CALL_FUNCTION_N_KW, MP_F_CALL_METHOD_N_KW, + MP_F_CALL_METHOD_N_KW_VAR, MP_F_GETITER, MP_F_ITERNEXT, MP_F_NLR_PUSH, |