diff options
author | Damien George <damien@micropython.org> | 2024-02-16 16:52:38 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-02-20 10:56:24 +1100 |
commit | 9400229766624e80db6a6f95af287a5542dc1b43 (patch) | |
tree | 58d10d8a89679faa09f19da993712127017b1870 | |
parent | 648a7578da21cc7ddb4046fc59891144e797b983 (diff) | |
download | micropython-9400229766624e80db6a6f95af287a5542dc1b43.tar.gz micropython-9400229766624e80db6a6f95af287a5542dc1b43.zip |
py/objfun: Split viper fun type out to separate mp_type_fun_viper type.
Viper functions are quite different to native functions and benefit from
being a separate type. For example, viper functions don't have a bytecode-
style prelude, and don't support generators or default arguments.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r-- | py/emitglue.c | 4 | ||||
-rw-r--r-- | py/obj.h | 1 | ||||
-rw-r--r-- | py/objfun.c | 21 | ||||
-rw-r--r-- | py/objfun.h | 10 |
4 files changed, 35 insertions, 1 deletions
diff --git a/py/emitglue.c b/py/emitglue.c index 7dc3080870..415aa3a3d3 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -199,13 +199,15 @@ mp_obj_t mp_make_function_from_proto_fun(mp_proto_fun_t proto_fun, const mp_modu switch (rc->kind) { #if MICROPY_EMIT_NATIVE case MP_CODE_NATIVE_PY: - case MP_CODE_NATIVE_VIPER: fun = mp_obj_new_fun_native(def_args, rc->fun_data, context, rc->children); // Check for a generator function, and if so change the type of the object if (rc->is_generator) { ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_gen_wrap; } break; + case MP_CODE_NATIVE_VIPER: + fun = mp_obj_new_fun_viper(rc->fun_data, context, rc->children); + break; #endif #if MICROPY_EMIT_INLINE_ASM case MP_CODE_NATIVE_ASM: @@ -834,6 +834,7 @@ extern const mp_obj_type_t mp_type_fun_builtin_3; extern const mp_obj_type_t mp_type_fun_builtin_var; extern const mp_obj_type_t mp_type_fun_bc; extern const mp_obj_type_t mp_type_fun_native; +extern const mp_obj_type_t mp_type_fun_viper; extern const mp_obj_type_t mp_type_fun_asm; extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_staticmethod; diff --git a/py/objfun.c b/py/objfun.c index ba0ba37068..1bdbb39166 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -428,6 +428,27 @@ MP_DEFINE_CONST_OBJ_TYPE( #endif // MICROPY_EMIT_NATIVE /******************************************************************************/ +/* viper functions */ + +#if MICROPY_EMIT_NATIVE + +STATIC mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + MP_STACK_CHECK(); + mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); + mp_call_fun_t fun = MICROPY_MAKE_POINTER_CALLABLE((void *)self->bytecode); + return fun(self_in, n_args, n_kw, args); +} + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_fun_viper, + MP_QSTR_function, + MP_TYPE_FLAG_BINDS_SELF, + call, fun_viper_call + ); + +#endif // MICROPY_EMIT_NATIVE + +/******************************************************************************/ /* inline assembler functions */ #if MICROPY_EMIT_INLINE_ASM diff --git a/py/objfun.h b/py/objfun.h index b6350d7b67..ddb148dd19 100644 --- a/py/objfun.h +++ b/py/objfun.h @@ -54,11 +54,21 @@ mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); #if MICROPY_EMIT_NATIVE + static inline mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) { mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(mp_obj_new_fun_bc(def_args, (const byte *)fun_data, mc, child_table)); o->base.type = &mp_type_fun_native; return MP_OBJ_FROM_PTR(o); } + +static inline mp_obj_t mp_obj_new_fun_viper(const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) { + mp_obj_fun_bc_t *o = mp_obj_malloc(mp_obj_fun_bc_t, &mp_type_fun_viper); + o->bytecode = fun_data; + o->context = mc; + o->child_table = child_table; + return MP_OBJ_FROM_PTR(o); +} + #endif #if MICROPY_EMIT_INLINE_ASM |