diff options
-rw-r--r-- | py/obj.h | 2 | ||||
-rw-r--r-- | py/runtime.c | 17 | ||||
-rw-r--r-- | tests/basics/tests/int-small.py | 26 |
3 files changed, 33 insertions, 12 deletions
@@ -34,6 +34,8 @@ typedef struct _mp_obj_base_t mp_obj_base_t; // - xxxx...xx10: a qstr, bits 2 and above are the value // - xxxx...xx00: a pointer to an mp_obj_base_t +// In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range +#define MP_OBJ_FITS_SMALL_INT(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0) #define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0) #define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2) #define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0) diff --git a/py/runtime.c b/py/runtime.c index 8d3e900286..2af86b6abd 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -268,10 +268,6 @@ void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_ar #endif } -static bool fit_small_int(mp_small_int_t o) { - return true; -} - int rt_is_true(mp_obj_t arg) { DEBUG_OP_printf("is true %p\n", arg); if (MP_OBJ_IS_SMALL_INT(arg)) { @@ -436,13 +432,10 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) { case RT_UNARY_OP_INVERT: val = ~val; break; default: assert(0); val = 0; } - if (fit_small_int(val)) { + if (MP_OBJ_FITS_SMALL_INT(val)) { return MP_OBJ_NEW_SMALL_INT(val); - } else { - // TODO make a bignum - assert(0); - return mp_const_none; } + return mp_obj_new_int(val); } else { // will be an object (small ints are caught in previous if) mp_obj_base_t *o = arg; if (o->type->unary_op != NULL) { @@ -551,11 +544,11 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { default: assert(0); } - if (fit_small_int(lhs_val)) { + // TODO: We just should make mp_obj_new_int() inline and use that + if (MP_OBJ_FITS_SMALL_INT(lhs_val)) { return MP_OBJ_NEW_SMALL_INT(lhs_val); } - // TODO: return long int - assert(0); + return mp_obj_new_int(lhs_val); } else if (MP_OBJ_IS_TYPE(rhs, &float_type)) { return mp_obj_float_binary_op(op, lhs_val, rhs); } else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) { diff --git a/tests/basics/tests/int-small.py b/tests/basics/tests/int-small.py new file mode 100644 index 0000000000..be338c4a4c --- /dev/null +++ b/tests/basics/tests/int-small.py @@ -0,0 +1,26 @@ +# This test small int range for 32-bit machine + +a = 0x3fffff +print(a) +a *= 0x10 +print(a) +a *= 0x10 +print(a) +a += 0xff +print(a) +# This would overflow +#a += 1 + +a = -0x3fffff +print(a) +a *= 0x10 +print(a) +a *= 0x10 +print(a) +a -= 0xff +print(a) +# This still doesn't overflow +a -= 1 +print(a) +# This would overflow +#a -= 1 |