summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2016-01-03 11:53:44 +0000
committerDamien George <damien.p.george@gmail.com>2016-01-03 11:53:44 +0000
commit1b0aab621baf081bf1cbeb38a29bd37fbc135cc7 (patch)
tree7128cdf6877636c1979e39c6fa925a8bbc649621 /py
parent3d2daa2d03e300ac64005b8659c31f04a0f7fd53 (diff)
downloadmicropython-1b0aab621baf081bf1cbeb38a29bd37fbc135cc7.tar.gz
micropython-1b0aab621baf081bf1cbeb38a29bd37fbc135cc7.zip
py: Change struct and macro for builtin fun so they can be type checked.
Diffstat (limited to 'py')
-rw-r--r--py/modbuiltins.c12
-rw-r--r--py/obj.h38
-rw-r--r--py/objfun.c12
3 files changed, 45 insertions, 17 deletions
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 9d1e90f578..ccb813e3ed 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -552,11 +552,19 @@ STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
+STATIC mp_obj_t mp_builtin_globals(void) {
+ return MP_OBJ_FROM_PTR(mp_globals_get());
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_builtin_globals);
+
+STATIC mp_obj_t mp_builtin_locals(void) {
+ return MP_OBJ_FROM_PTR(mp_locals_get());
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_builtin_locals);
+
// These are defined in terms of MicroPython API functions right away
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_id_obj, mp_obj_id);
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_len_obj, mp_obj_len);
-MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_globals_get);
-MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_locals_get);
STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = {
// built-in core functions
diff --git a/py/obj.h b/py/obj.h
index 3d9c00c52f..509d6a67b5 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -270,14 +270,27 @@ static inline bool mp_obj_is_integer(mp_const_obj_t o) { return MP_OBJ_IS_INT(o)
#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_builtin_t obj_name
-#define MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, is_kw, n_args_min, n_args_max, fun_name) const mp_obj_fun_builtin_t obj_name = {{&mp_type_fun_builtin}, is_kw, n_args_min, n_args_max, (void(*)(void))fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 0, 0, (mp_fun_0_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 1, 1, (mp_fun_1_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 2, 2, (mp_fun_2_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, MP_OBJ_FUN_ARGS_MAX, (mp_fun_var_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, (mp_fun_kw_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, false, 0, 0, .fun._0 = fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, false, 1, 1, .fun._1 = fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, false, 2, 2, .fun._2 = fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, false, 3, 3, .fun._3 = fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, false, n_args_min, MP_OBJ_FUN_ARGS_MAX, .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_t obj_name = \
+ {{&mp_type_fun_builtin}, false, n_args_min, n_args_max, .fun.var = fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \
+ const mp_obj_fun_builtin_t obj_name = \
+ {{&mp_type_fun_builtin}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .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
@@ -744,7 +757,14 @@ typedef struct _mp_obj_fun_builtin_t { // use this to make const objects that go
bool is_kw : 1;
mp_uint_t n_args_min : 15; // inclusive
mp_uint_t n_args_max : 16; // inclusive
- void (*fun)(void); // must be a pointer to a callable function in ROM
+ union {
+ mp_fun_0_t _0;
+ mp_fun_1_t _1;
+ mp_fun_2_t _2;
+ mp_fun_3_t _3;
+ mp_fun_var_t var;
+ mp_fun_kw_t kw;
+ } fun;
} mp_obj_fun_builtin_t;
qstr mp_obj_fun_get_name(mp_const_obj_t fun);
diff --git a/py/objfun.c b/py/objfun.c
index 34938ccfdd..a574926ba5 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -66,7 +66,7 @@ STATIC mp_obj_t fun_builtin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- return ((mp_fun_kw_t)self->fun)(n_args, args, &kw_args);
+ return self->fun.kw(n_args, args, &kw_args);
} else if (self->n_args_min <= 3 && self->n_args_min == self->n_args_max) {
// function requires a fixed number of arguments
@@ -74,23 +74,23 @@ STATIC mp_obj_t fun_builtin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n
// dispatch function call
switch (self->n_args_min) {
case 0:
- return ((mp_fun_0_t)self->fun)();
+ return self->fun._0();
case 1:
- return ((mp_fun_1_t)self->fun)(args[0]);
+ return self->fun._1(args[0]);
case 2:
- return ((mp_fun_2_t)self->fun)(args[0], args[1]);
+ return self->fun._2(args[0], args[1]);
case 3:
default:
- return ((mp_fun_3_t)self->fun)(args[0], args[1], args[2]);
+ return self->fun._3(args[0], args[1], args[2]);
}
} else {
// function takes a variable number of arguments, but no keywords
- return ((mp_fun_var_t)self->fun)(n_args, args);
+ return self->fun.var(n_args, args);
}
}