py: More robust int conversion and overflow checking.
diff --git a/py/mpz.c b/py/mpz.c
index 79d200d..4a8941e 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -1139,6 +1139,7 @@
 }
 #endif
 
+// TODO check that this correctly handles overflow in all cases
 machine_int_t mpz_as_int(const mpz_t *i) {
     machine_int_t val = 0;
     mpz_dig_t *d = i->dig + i->len;
@@ -1147,11 +1148,13 @@
         machine_int_t oldval = val;
         val = (val << DIG_SIZE) | *d;
         if (val < oldval) {
-            // TODO need better handling of conversion overflow
+            // overflow, return +/- "infinity"
             if (i->neg == 0) {
-                return 0x7fffffff;
+                // +infinity
+                return ~WORD_MSBIT_HIGH;
             } else {
-                return 0x80000000;
+                // -infinity
+                return WORD_MSBIT_HIGH;
             }
         }
     }
@@ -1163,6 +1166,28 @@
     return val;
 }
 
+// TODO check that this correctly handles overflow in all cases
+bool mpz_as_int_checked(const mpz_t *i, machine_int_t *value) {
+    machine_int_t val = 0;
+    mpz_dig_t *d = i->dig + i->len;
+
+    while (--d >= i->dig) {
+        machine_int_t oldval = val;
+        val = (val << DIG_SIZE) | *d;
+        if (val < oldval) {
+            // overflow
+            return false;
+        }
+    }
+
+    if (i->neg != 0) {
+        val = -val;
+    }
+
+    *value = val;
+    return true;
+}
+
 #if MICROPY_ENABLE_FLOAT
 mp_float_t mpz_as_float(const mpz_t *i) {
     mp_float_t val = 0;
diff --git a/py/mpz.h b/py/mpz.h
index 7778893..cbe60eb 100644
--- a/py/mpz.h
+++ b/py/mpz.h
@@ -71,6 +71,7 @@
 mpz_t *mpz_mod(const mpz_t *lhs, const mpz_t *rhs);
 
 machine_int_t mpz_as_int(const mpz_t *z);
+bool mpz_as_int_checked(const mpz_t *z, machine_int_t *value);
 #if MICROPY_ENABLE_FLOAT
 mp_float_t mpz_as_float(const mpz_t *z);
 #endif
diff --git a/py/obj.c b/py/obj.c
index 95052d1..bf3e1d5 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -203,6 +203,24 @@
     }
 }
 
+// returns false if arg is not of integral type
+// returns true and sets *value if it is of integral type
+// can throw OverflowError if arg is of integral type, but doesn't fit in a machine_int_t
+bool mp_obj_get_int_maybe(mp_obj_t arg, machine_int_t *value) {
+    if (arg == mp_const_false) {
+        *value = 0;
+    } else if (arg == mp_const_true) {
+        *value = 1;
+    } else if (MP_OBJ_IS_SMALL_INT(arg)) {
+        *value = MP_OBJ_SMALL_INT_VALUE(arg);
+    } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) {
+        *value = mp_obj_int_get_checked(arg);
+    } else {
+        return false;
+    }
+    return true;
+}
+
 #if MICROPY_ENABLE_FLOAT
 mp_float_t mp_obj_get_float(mp_obj_t arg) {
     if (arg == mp_const_false) {
diff --git a/py/obj.h b/py/obj.h
index 952187e..f5ce873 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -359,6 +359,7 @@
 bool mp_obj_less(mp_obj_t o1, mp_obj_t o2);
 
 machine_int_t mp_obj_get_int(mp_obj_t arg);
+bool mp_obj_get_int_maybe(mp_obj_t arg, machine_int_t *value);
 #if MICROPY_ENABLE_FLOAT
 mp_float_t mp_obj_get_float(mp_obj_t self_in);
 void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 27f77d1..25a069c 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -243,8 +243,18 @@
 }
 
 machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) {
-    // TODO: Check overflow
-    return mp_obj_int_get(self_in);
+    if (MP_OBJ_IS_SMALL_INT(self_in)) {
+        return MP_OBJ_SMALL_INT_VALUE(self_in);
+    } else {
+        mp_obj_int_t *self = self_in;
+        machine_int_t value;
+        if (mpz_as_int_checked(&self->mpz, &value)) {
+            return value;
+        } else {
+            // overflow
+            nlr_jump(mp_obj_new_exception_msg(&mp_type_OverflowError, "overflow converting long int to machine word"));
+        }
+    }
 }
 
 #if MICROPY_ENABLE_FLOAT
diff --git a/py/objlist.c b/py/objlist.c
index 244d4a5..2a5f2c8 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -122,12 +122,11 @@
             list_extend(lhs, rhs);
             return o;
         }
-        case MP_BINARY_OP_MULTIPLY:
-        {
-            if (!MP_OBJ_IS_SMALL_INT(rhs)) {
+        case MP_BINARY_OP_MULTIPLY: {
+            machine_int_t n;
+            if (!mp_obj_get_int_maybe(rhs, &n)) {
                 return NULL;
             }
-            int n = MP_OBJ_SMALL_INT_VALUE(rhs);
             mp_obj_list_t *s = list_new(o->len * n);
             mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
             return s;