From fc245d1ca4367f9876ac32c7e08e169da7db79b9 Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Tue, 4 Apr 2017 16:45:49 +1000
Subject: [PATCH] py/objint: Consolidate mp_obj_new_int_from_float to one
 implementation.

This reduces code duplication and allows to make mp_classify_fp_as_int
static, which reduces code size.
---
 py/objint.c          | 56 +++++++++++++++++++++++++++++---------------
 py/objint.h          | 11 +++------
 py/objint_longlong.c | 20 ----------------
 py/objint_mpz.c      | 22 +----------------
 4 files changed, 41 insertions(+), 68 deletions(-)

diff --git a/py/objint.c b/py/objint.c
index 2e8fe4f22..46f9b1666 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -80,7 +80,14 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args,
 }
 
 #if MICROPY_PY_BUILTINS_FLOAT
-mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
+
+typedef enum {
+    MP_FP_CLASS_FIT_SMALLINT,
+    MP_FP_CLASS_FIT_LONGINT,
+    MP_FP_CLASS_OVERFLOW
+} mp_fp_as_int_class_t;
+
+STATIC mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
     union {
         mp_float_t f;
 #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
@@ -130,6 +137,35 @@ mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
 }
 #undef MP_FLOAT_SIGN_SHIFT_I32
 #undef MP_FLOAT_EXP_SHIFT_I32
+
+mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
+    int cl = fpclassify(val);
+    if (cl == FP_INFINITE) {
+        nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "can't convert inf to int"));
+    } else if (cl == FP_NAN) {
+        mp_raise_ValueError("can't convert NaN to int");
+    } else {
+        mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
+        if (icl == MP_FP_CLASS_FIT_SMALLINT) {
+            return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
+        #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
+        } else {
+            mp_obj_int_t *o = mp_obj_int_new_mpz();
+            mpz_set_from_float(&o->mpz, val);
+            return MP_OBJ_FROM_PTR(o);
+        }
+        #else
+        #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
+        } else if (icl == MP_FP_CLASS_FIT_LONGINT) {
+            return mp_obj_new_int_from_ll((long long)val);
+        #endif
+        } else {
+            mp_raise_ValueError("float too big");
+        }
+        #endif
+    }
+}
+
 #endif
 
 #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
@@ -323,24 +359,6 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
     return mp_const_none;
 }
 
-#if MICROPY_PY_BUILTINS_FLOAT
-mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
-    int cl = fpclassify(val);
-    if (cl == FP_INFINITE) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
-    } else if (cl == FP_NAN) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
-    } else {
-        mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
-        if (icl == MP_FP_CLASS_FIT_SMALLINT) {
-            return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
-        } else {
-            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "float too big"));
-        }
-    }
-}
-#endif
-
 mp_obj_t mp_obj_new_int(mp_int_t value) {
     if (MP_SMALL_INT_FITS(value)) {
         return MP_OBJ_NEW_SMALL_INT(value);
diff --git a/py/objint.h b/py/objint.h
index 7205761ad..da56c1862 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -41,18 +41,13 @@ typedef struct _mp_obj_int_t {
 extern const mp_obj_int_t mp_maxsize_obj;
 
 #if MICROPY_PY_BUILTINS_FLOAT
-typedef enum {
-    MP_FP_CLASS_FIT_SMALLINT,
-    MP_FP_CLASS_FIT_LONGINT,
-    MP_FP_CLASS_OVERFLOW
-} mp_fp_as_int_class_t;
-
-mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val);
 mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in);
-#endif // MICROPY_PY_BUILTINS_FLOAT
+#endif
 
 size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma);
 
+mp_obj_int_t *mp_obj_int_new_mpz(void);
+
 void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
 char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
                            int base, const char *prefix, char base_char, char comma);
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index 4ab49f337..540cfebd0 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -263,26 +263,6 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
     return o;
 }
 
-#if MICROPY_PY_BUILTINS_FLOAT
-mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
-    int cl = fpclassify(val);
-    if (cl == FP_INFINITE) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
-    } else if (cl == FP_NAN) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
-    } else {
-        mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
-        if (icl == MP_FP_CLASS_FIT_SMALLINT) {
-            return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
-        } else if (icl == MP_FP_CLASS_FIT_LONGINT) {
-            return mp_obj_new_int_from_ll((long long)val);
-        } else {
-            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "float too big"));
-        }
-    }
-}
-#endif
-
 mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) {
     // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated
     // TODO check overflow
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index ca989e8ad..2353bd8d6 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -74,7 +74,7 @@ const mp_obj_int_t mp_maxsize_obj = {
 #undef NUM_DIG
 #endif
 
-STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) {
+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;
     mpz_init_zero(&o->mpz);
@@ -387,26 +387,6 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
     return mp_obj_new_int_from_ull(value);
 }
 
-#if MICROPY_PY_BUILTINS_FLOAT
-mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
-    int cl = fpclassify(val);
-    if (cl == FP_INFINITE) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
-    } else if (cl == FP_NAN) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
-    } else {
-        mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
-        if (icl == MP_FP_CLASS_FIT_SMALLINT) {
-            return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
-        } else {
-            mp_obj_int_t *o = mp_obj_int_new_mpz();
-            mpz_set_from_float(&o->mpz, val);
-            return MP_OBJ_FROM_PTR(o);
-        }
-    }
-}
-#endif
-
 mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) {
     mp_obj_int_t *o = mp_obj_int_new_mpz();
     size_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base);
-- 
GitLab