From 176ab99180a95eeac8794828f2f751a696571bb5 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Mon, 13 Jan 2020 23:35:07 +0200 Subject: [PATCH] py/objint: Add mp_obj_int_get_uint_checked() helper. Can be used where mp_obj_int_get_checked() will overflow due to the sign-bit solely. This returns an mp_uint_t, so it also verifies the given integer is not negative. Currently implemented only for mpz configurations. --- py/obj.h | 2 ++ py/objint_mpz.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/py/obj.h b/py/obj.h index 93433f924d..ba4f4992ff 100644 --- a/py/obj.h +++ b/py/obj.h @@ -748,6 +748,8 @@ void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj); mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in); // Will raise exception if value doesn't fit into mp_int_t mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in); +// Will raise exception if value is negative or doesn't fit into mp_uint_t +mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in); // exception #define mp_obj_is_native_exception_instance(o) (mp_obj_get_type(o)->make_new == mp_obj_exception_make_new) diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 121fd03424..2c09d9bd2b 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -411,6 +411,22 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { } } +mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) { + if (mp_obj_is_small_int(self_in)) { + if (MP_OBJ_SMALL_INT_VALUE(self_in) >= 0) { + return MP_OBJ_SMALL_INT_VALUE(self_in); + } + } else { + const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t value; + if (mpz_as_uint_checked(&self->mpz, &value)) { + return value; + } + } + + mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word"); +} + #if MICROPY_PY_BUILTINS_FLOAT mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) { assert(mp_obj_is_type(self_in, &mp_type_int));