Skip to content

Commit cc164aa

Browse files
committed
py: Make struct-initializing macros compatible with C++.
This requires explicitly naming and initializing all members. To verify this is done correctly add coverage code calling these macros. Signed-off-by: stijn <stijn@ignitron.net>
1 parent 5eee5a6 commit cc164aa

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

ports/unix/coveragecpp.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,48 @@ extern "C" {
1717
#include <py/runtime.h>
1818
}
1919

20+
// Invoke all (except one, see below) public API macros which initialize structs to make sure
21+
// they are C++-compatible, meaning they explicitly initialize all struct members.
22+
mp_obj_t f0();
23+
MP_DEFINE_CONST_FUN_OBJ_0(f0_obj, f0);
24+
mp_obj_t f1(mp_obj_t);
25+
MP_DEFINE_CONST_FUN_OBJ_1(f1_obj, f1);
26+
mp_obj_t f2(mp_obj_t, mp_obj_t);
27+
MP_DEFINE_CONST_FUN_OBJ_2(f2_obj, f2);
28+
mp_obj_t f3(mp_obj_t, mp_obj_t, mp_obj_t);
29+
MP_DEFINE_CONST_FUN_OBJ_3(f3_obj, f3);
30+
mp_obj_t fvar(size_t, const mp_obj_t *);
31+
MP_DEFINE_CONST_FUN_OBJ_VAR(fvar_obj, 1, fvar);
32+
mp_obj_t fvarbetween(size_t, const mp_obj_t *);
33+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fvarbetween_obj, 1, 2, fvarbetween);
34+
mp_obj_t fkw(size_t, const mp_obj_t *, mp_map_t *);
35+
MP_DEFINE_CONST_FUN_OBJ_KW(fkw_obj, 1, fkw);
36+
37+
static const mp_rom_map_elem_t table[] = {
38+
{ MP_ROM_QSTR(MP_QSTR_f0), MP_ROM_PTR(&f0_obj) },
39+
};
40+
MP_DEFINE_CONST_MAP(map, table);
41+
MP_DEFINE_CONST_DICT(dict, table);
42+
43+
static const qstr attrtuple_fields[] = {
44+
MP_QSTR_f0,
45+
};
46+
MP_DEFINE_ATTRTUPLE(attrtuple, attrtuple_fields, 1, MP_ROM_PTR(&f0_obj));
47+
48+
void cb(void *);
49+
MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctf, cb,(void *) cb);
50+
51+
// The MP_DEFINE_CONST_OBJ_TYPE macro is not C++-compatible because each of the
52+
// MP_DEFINE_CONST_OBJ_TYPE_NARGS_X macros only initializes some of _mp_obj_type_t's
53+
// .slot_index_xxx members but that cannot be fixed to be done in a deterministic way.
54+
55+
2056
#if defined(MICROPY_UNIX_COVERAGE)
2157

2258
// Just to test building of C++ code.
2359
static mp_obj_t extra_cpp_coverage_impl() {
60+
// void *p = MP_ROM_PTR(&rom_obj);
61+
// (void) p;
2462
return mp_const_none;
2563
}
2664

py/obj.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,25 +371,25 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t;
371371

372372
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \
373373
const mp_obj_fun_builtin_fixed_t obj_name = \
374-
{{&mp_type_fun_builtin_0}, .fun._0 = fun_name}
374+
{.base = {.type = &mp_type_fun_builtin_0}, .fun = {._0 = fun_name}}
375375
#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) \
376376
const mp_obj_fun_builtin_fixed_t obj_name = \
377-
{{&mp_type_fun_builtin_1}, .fun._1 = fun_name}
377+
{.base = {.type = &mp_type_fun_builtin_1}, .fun = {._1 = fun_name}}
378378
#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) \
379379
const mp_obj_fun_builtin_fixed_t obj_name = \
380-
{{&mp_type_fun_builtin_2}, .fun._2 = fun_name}
380+
{.base = {.type = &mp_type_fun_builtin_2}, .fun = {._2 = fun_name}}
381381
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) \
382382
const mp_obj_fun_builtin_fixed_t obj_name = \
383-
{{&mp_type_fun_builtin_3}, .fun._3 = fun_name}
383+
{.base = {.type = &mp_type_fun_builtin_3}, .fun = {._3 = fun_name}}
384384
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) \
385385
const mp_obj_fun_builtin_var_t obj_name = \
386-
{{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, false), .fun.var = fun_name}
386+
{.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, false), .fun = {.var = fun_name}}
387387
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) \
388388
const mp_obj_fun_builtin_var_t obj_name = \
389-
{{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun.var = fun_name}
389+
{.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun = {.var = fun_name}}
390390
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \
391391
const mp_obj_fun_builtin_var_t obj_name = \
392-
{{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun.kw = fun_name}
392+
{.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun = {.kw = fun_name}}
393393

394394
// These macros are used to define constant map/dict objects
395395
// You can put "static" in front of the definition to make it local

py/objtuple.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ extern const mp_obj_type_t mp_type_attrtuple;
5050

5151
#define MP_DEFINE_ATTRTUPLE(tuple_obj_name, fields, nitems, ...) \
5252
const mp_rom_obj_tuple_t tuple_obj_name = { \
53-
.base = {&mp_type_attrtuple}, \
53+
.base = {.type = &mp_type_attrtuple}, \
5454
.len = nitems, \
5555
.items = { __VA_ARGS__, MP_ROM_PTR((void *)fields) } \
5656
}

py/runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
// For use with mp_call_function_1_from_nlr_jump_callback.
3434
#define MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, f, a) \
3535
nlr_jump_callback_node_call_function_1_t ctx = { \
36+
.callback = {.prev = NULL, .fun = NULL}, \
3637
.func = (void (*)(void *))(f), \
3738
.arg = (a), \
3839
}

0 commit comments

Comments
 (0)