From d9433d3e9497a4ec4cd51eb78d6ca602f310ce91 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Wed, 22 Jan 2020 13:19:14 +0100 Subject: [PATCH] py/obj.h: Add and use mp_obj_is_bool() helper. Commit d96cfd13e3a464862cecffb2718c6286b52c77b0 introduced a regression in testing for bool objects, that such objects were in some cases no longer recognised and bools, eg when using mp_obj_is_type(o, &mp_type_bool), or mp_obj_is_integer(o). This commit fixes that problem by adding mp_obj_is_bool(o). Builds with MICROPY_OBJ_IMMEDIATE_OBJS enabled check if the object is any of the const True or False objects. Builds without it use the old method of ->type checking, which compiles to smaller code (compared with the former mentioned method). Fixes #5538. --- py/obj.h | 8 +++++++- py/objstr.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/py/obj.h b/py/obj.h index ba4f4992ff..b052b9fc8b 100644 --- a/py/obj.h +++ b/py/obj.h @@ -665,6 +665,12 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; // Note: these are kept as macros because inline functions sometimes use much // more code space than the equivalent macros, depending on the compiler. #define mp_obj_is_type(o, t) (mp_obj_is_obj(o) && (((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type == (t))) // this does not work for checking int, str or fun; use below macros for that +#if MICROPY_OBJ_IMMEDIATE_OBJS +// bool's are immediates, not real objects, so test for the 2 possible values. +#define mp_obj_is_bool(o) ((o) == mp_const_false || (o) == mp_const_true) +#else +#define mp_obj_is_bool(o) mp_obj_is_type(o, &mp_type_bool) +#endif #define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_type(o, &mp_type_int)) #define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_type(o, &mp_type_str)) #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) @@ -721,7 +727,7 @@ bool mp_obj_is_true(mp_obj_t arg); bool mp_obj_is_callable(mp_obj_t o_in); bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); -static inline bool mp_obj_is_integer(mp_const_obj_t o) { return mp_obj_is_int(o) || mp_obj_is_type(o, &mp_type_bool); } // returns true if o is bool, small int or long int +static inline bool mp_obj_is_integer(mp_const_obj_t o) { return mp_obj_is_int(o) || mp_obj_is_bool(o); } // returns true if o is bool, small int or long int mp_int_t mp_obj_get_int(mp_const_obj_t arg); mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg); bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value); diff --git a/py/objstr.c b/py/objstr.c index 454d1cbcc5..7e7e86dddc 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -910,7 +910,7 @@ STATIC bool istype(char ch) { } STATIC bool arg_looks_integer(mp_obj_t arg) { - return mp_obj_is_type(arg, &mp_type_bool) || mp_obj_is_int(arg); + return mp_obj_is_bool(arg) || mp_obj_is_int(arg); } STATIC bool arg_looks_numeric(mp_obj_t arg) {