diff options
| author | Damien George <damien.p.george@gmail.com> | 2014-04-08 23:30:46 +0100 |
|---|---|---|
| committer | Damien George <damien.p.george@gmail.com> | 2014-04-08 23:30:46 +0100 |
| commit | 88d7bba961cb38c594d72b6be5847cb1106f91b2 (patch) | |
| tree | 4d49fb9d1c61148dde6e3429ccb950449e3f3581 /py/objint_mpz.c | |
| parent | 803b9263ab1049d19d62d9a09e5f82084b7afa41 (diff) | |
py: Make it so that printing a small int does not allocate heap memory.
With the implementation of proper string formatting, code to print a
small int was delegated to mpz_as_str_inpl (after first converting the
small int to an mpz using stack memory). But mpz_as_str_inpl allocates
heap memory to do the conversion, so small ints needed heap memory just
to be printed.
This fix has a separate function to print small ints, which does not
allocate heap, and allocates less stack.
String formatting, printf and pfenv are now large beasts, with some
semi-duplicated code.
Diffstat (limited to 'py/objint_mpz.c')
| -rw-r--r-- | py/objint_mpz.c | 26 |
1 files changed, 9 insertions, 17 deletions
diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 6410ecc64..583ce4cb7 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -1,6 +1,7 @@ #include <stdint.h> #include <string.h> #include <stdio.h> +#include <assert.h> #include "nlr.h" #include "misc.h" @@ -29,30 +30,21 @@ STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) { // // The resulting formatted string will be returned from this function and the // formatted size will be in *fmt_size. -char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, - int base, const char *prefix, char base_char, char comma) { - mpz_t small_mpz; - mpz_t *mpz; - mpz_dig_t small_dig[(sizeof(mp_small_int_t) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE]; - - if (MP_OBJ_IS_SMALL_INT(self_in)) { - mpz_init_fixed_from_int(&small_mpz, small_dig, - sizeof(small_dig) / sizeof(small_dig[0]), - MP_OBJ_SMALL_INT_VALUE(self_in)); - mpz = &small_mpz; - } else { - mp_obj_int_t *self = self_in; - mpz = &self->mpz; - } +// +// This particular routine should only be called for the mpz representation of the int. +char *mp_obj_int_formatted_impl(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, + int base, const char *prefix, char base_char, char comma) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + mp_obj_int_t *self = self_in; - uint needed_size = mpz_as_str_size_formatted(mpz, base, prefix, comma); + uint needed_size = mpz_as_str_size_formatted(&self->mpz, base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; } char *str = *buf; - *fmt_size = mpz_as_str_inpl(mpz, base, prefix, base_char, comma, str); + *fmt_size = mpz_as_str_inpl(&self->mpz, base, prefix, base_char, comma, str); return str; } |
