summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/argcheck.c7
-rw-r--r--py/obj.h14
-rw-r--r--py/objfun.c4
-rw-r--r--py/runtime.h5
4 files changed, 19 insertions, 11 deletions
diff --git a/py/argcheck.c b/py/argcheck.c
index d53bca73a6..c018f3fe78 100644
--- a/py/argcheck.c
+++ b/py/argcheck.c
@@ -29,9 +29,14 @@
#include "py/runtime.h"
-void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
+void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) {
// TODO maybe take the function name as an argument so we can print nicer error messages
+ // The reverse of MP_OBJ_FUN_MAKE_SIG
+ bool takes_kw = sig & 1;
+ size_t n_args_min = sig >> 17;
+ size_t n_args_max = (sig >> 1) & 0xffff;
+
if (n_kw && !takes_kw) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_arg_error_terse_mismatch();
diff --git a/py/obj.h b/py/obj.h
index f9bdb59d5a..4a371bc636 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -277,6 +277,9 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
#define MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name) extern const mp_obj_fun_builtin_var_t obj_name
#define MP_DECLARE_CONST_FUN_OBJ_KW(obj_name) extern const mp_obj_fun_builtin_var_t obj_name
+#define MP_OBJ_FUN_ARGS_MAX (0xffff) // to set maximum value in n_args_max below
+#define MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, takes_kw) (((n_args_min) << 17) | ((n_args_max) << 1) | (takes_kw))
+
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \
const mp_obj_fun_builtin_fixed_t obj_name = \
{{&mp_type_fun_builtin_0}, .fun._0 = fun_name}
@@ -291,13 +294,13 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
{{&mp_type_fun_builtin_3}, .fun._3 = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) \
const mp_obj_fun_builtin_var_t obj_name = \
- {{&mp_type_fun_builtin_var}, false, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.var = fun_name}
+ {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, false), .fun.var = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) \
const mp_obj_fun_builtin_var_t obj_name = \
- {{&mp_type_fun_builtin_var}, false, n_args_min, n_args_max, .fun.var = fun_name}
+ {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun.var = fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \
const mp_obj_fun_builtin_var_t obj_name = \
- {{&mp_type_fun_builtin_var}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.kw = fun_name}
+ {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun.kw = fun_name}
// These macros are used to define constant map/dict objects
// You can put "static" in front of the definition to make it local
@@ -785,12 +788,9 @@ typedef struct _mp_obj_fun_builtin_fixed_t {
} fun;
} mp_obj_fun_builtin_fixed_t;
-#define MP_OBJ_FUN_ARGS_MAX (0xffff) // to set maximum value in n_args_max below
typedef struct _mp_obj_fun_builtin_var_t {
mp_obj_base_t base;
- bool is_kw : 1;
- mp_uint_t n_args_min : 15; // inclusive
- mp_uint_t n_args_max : 16; // inclusive
+ uint32_t sig; // see MP_OBJ_FUN_MAKE_SIG
union {
mp_fun_var_t var;
mp_fun_kw_t kw;
diff --git a/py/objfun.c b/py/objfun.c
index df377441e0..e7f2b79ada 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -110,9 +110,9 @@ STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k
mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in);
// check number of arguments
- mp_arg_check_num(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw);
+ mp_arg_check_num_sig(n_args, n_kw, self->sig);
- if (self->is_kw) {
+ if (self->sig & 1) {
// function allows keywords
// we create a map directly from the given args array
diff --git a/py/runtime.h b/py/runtime.h
index 99a2204aaf..dd4c9a984e 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -77,7 +77,10 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg);
// extra printing method specifically for mp_obj_t's which are integral type
int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec);
-void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw);
+void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig);
+static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
+ mp_arg_check_num_sig(n_args, n_kw, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, takes_kw));
+}
void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
NORETURN void mp_arg_error_terse_mismatch(void);