From 4e0eeebdc2b452277c24f554c444f0cc0de9e4ea Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 3 Jul 2014 16:50:11 +0300 Subject: [PATCH] py: Implement sys.maxsize, standard way to check platform "bitness". Implementing it as a static constant is a bit peculiar and require cooperation from long int implementation. --- py/modsys.c | 19 +++++++++++++++++++ py/mpconfig.h | 5 +++++ py/objint_longlong.c | 5 +++++ py/objint_mpz.c | 20 ++++++++++++++++++++ py/qstrdefs.h | 3 +++ unix/mpconfigport.h | 1 + 6 files changed, 53 insertions(+) diff --git a/py/modsys.c b/py/modsys.c index 1e7f7eff7f..d215846762 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include +#include #include "mpconfig.h" #include "misc.h" #include "qstr.h" @@ -33,6 +35,8 @@ #include "objlist.h" #include "objtuple.h" #include "objstr.h" +#include "mpz.h" +#include "objint.h" #if MICROPY_PY_SYS @@ -44,6 +48,8 @@ extern struct _dummy_t mp_sys_stdin_obj; extern struct _dummy_t mp_sys_stdout_obj; extern struct _dummy_t mp_sys_stderr_obj; +extern mp_obj_int_t mp_maxsize_obj; + mp_obj_list_t mp_sys_path_obj; mp_obj_list_t mp_sys_argv_obj; #define I(n) MP_OBJ_NEW_SMALL_INT(n) @@ -70,6 +76,19 @@ STATIC const mp_map_elem_t mp_module_sys_globals_table[] = { #else { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_big) }, #endif +#if MICROPY_PY_SYS_MAXSIZE + #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE + // INT_MAX is not representable as small int, as we know that small int + // takes one bit for tag. So, we have little choice but to provide this + // value. Apps also should be careful to not try to compare sys.maxsize + // with some number (which may not fit in available int size), but instead + // count number of significant bits in sys.maxsize. + { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(INT_MAX >> 1) }, + #else + { MP_OBJ_NEW_QSTR(MP_QSTR_maxsize), (mp_obj_t)&mp_maxsize_obj }, + #endif +#endif + #if MICROPY_PY_SYS_EXIT { MP_OBJ_NEW_QSTR(MP_QSTR_exit), (mp_obj_t)&mp_sys_exit_obj }, diff --git a/py/mpconfig.h b/py/mpconfig.h index da9cffc56a..c04c69c639 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -336,6 +336,11 @@ typedef double mp_float_t; #define MICROPY_PY_SYS (1) #endif +// Whether to provide "sys.maxsize" constant +#ifndef MICROPY_PY_SYS_MAXSIZE +#define MICROPY_PY_SYS_MAXSIZE (0) +#endif + // Whether to provide "sys.exit" function #ifndef MICROPY_PY_SYS_EXIT #define MICROPY_PY_SYS_EXIT (0) diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 13e3b4811a..637d9c32c9 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -50,6 +50,11 @@ #define SUFFIX "" #endif +#if MICROPY_PY_SYS_MAXSIZE +// Export value for sys.maxsize +const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, INT_MAX}; +#endif + bool mp_obj_int_is_positive(mp_obj_t self_in) { if (MP_OBJ_IS_SMALL_INT(self_in)) { return MP_OBJ_SMALL_INT_VALUE(self_in) >= 0; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index da02b1ea9b..6e1c3c5a84 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -43,6 +43,26 @@ #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ +#if MICROPY_PY_SYS_MAXSIZE +// Export value for sys.maxsize +#define DIG_MASK ((1 << MPZ_DIG_SIZE) - 1) +STATIC const mpz_dig_t maxsize_dig[MPZ_NUM_DIG_FOR_INT] = { + (INT_MAX >> MPZ_DIG_SIZE * 0) & DIG_MASK, + (INT_MAX >> MPZ_DIG_SIZE * 1) & DIG_MASK, + (INT_MAX >> MPZ_DIG_SIZE * 2) & DIG_MASK, + #if (INT_MAX >> MPZ_DIG_SIZE * 2) > DIG_MASK + (INT_MAX >> MPZ_DIG_SIZE * 3) & DIG_MASK, + (INT_MAX >> MPZ_DIG_SIZE * 4) & DIG_MASK, +// (INT_MAX >> MPZ_DIG_SIZE * 5) & DIG_MASK, + #endif +}; +const mp_obj_int_t mp_maxsize_obj = { + {&mp_type_int}, + {.fixed_dig = 1, .len = MPZ_NUM_DIG_FOR_INT, .alloc = MPZ_NUM_DIG_FOR_INT, .dig = (mpz_dig_t*)maxsize_dig} +}; +#undef DIG_MASK +#endif + STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) { mp_obj_int_t *o = m_new_obj(mp_obj_int_t); o->base.type = &mp_type_int; diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 4ff9ca87c8..6fbfabde67 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -352,6 +352,9 @@ Q(stdout) Q(stderr) Q(version) Q(version_info) +#if MICROPY_PY_SYS_MAXSIZE +Q(maxsize) +#endif #endif #if MICROPY_PY_STRUCT diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index 002ea79f94..98132ac6e7 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -45,6 +45,7 @@ #define MICROPY_PY_BUILTINS_FROZENSET (1) #define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_PLATFORM "linux" +#define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_CMATH (1) #define MICROPY_PY_IO_FILEIO (1)