From 9e8f3163924c1f429f16f44a4a27b0cd33064719 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 21 Apr 2017 16:40:57 +0300 Subject: [PATCH] extmod/moductypes: Fix bigint handling for 32-bit ports. --- extmod/moductypes.c | 2 +- py/objint_mpz.c | 1 + tests/extmod/uctypes_32bit_intbig.py | 54 ++++++++++++++++++++++++ tests/extmod/uctypes_32bit_intbig.py.exp | 11 +++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/extmod/uctypes_32bit_intbig.py create mode 100644 tests/extmod/uctypes_32bit_intbig.py.exp diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 6249a49406..d2d2e85de1 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -360,7 +360,7 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) { return; } #endif - mp_int_t v = mp_obj_get_int(val); + mp_int_t v = mp_obj_get_int_truncated(val); switch (val_type) { case UINT8: ((uint8_t*)p)[index] = (uint8_t)v; return; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 2353bd8d68..d818b6f407 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -116,6 +116,7 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); + memset(buf, 0, len); mpz_as_bytes(&self->mpz, big_endian, len, buf); } diff --git a/tests/extmod/uctypes_32bit_intbig.py b/tests/extmod/uctypes_32bit_intbig.py new file mode 100644 index 0000000000..a082dc3704 --- /dev/null +++ b/tests/extmod/uctypes_32bit_intbig.py @@ -0,0 +1,54 @@ +# This test checks previously known problem values for 32-bit ports. +# It's less useful for 64-bit ports. +try: + import uctypes +except ImportError: + import sys + print("SKIP") + sys.exit() + +buf = b"12345678abcd" +struct = uctypes.struct( + uctypes.addressof(buf), + {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4}, + uctypes.LITTLE_ENDIAN +) + +struct.f32 = 0x7fffffff +print(buf) + +struct.f32 = 0x80000000 +print(buf) + +struct.f32 = 0xff010203 +print(buf) + +struct.f64 = 0x80000000 +print(buf) + +struct.f64 = 0x80000000 * 2 +print(buf) + +print("=") + +buf = b"12345678abcd" +struct = uctypes.struct( + uctypes.addressof(buf), + {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4}, + uctypes.BIG_ENDIAN +) + +struct.f32 = 0x7fffffff +print(buf) + +struct.f32 = 0x80000000 +print(buf) + +struct.f32 = 0xff010203 +print(buf) + +struct.f64 = 0x80000000 +print(buf) + +struct.f64 = 0x80000000 * 2 +print(buf) diff --git a/tests/extmod/uctypes_32bit_intbig.py.exp b/tests/extmod/uctypes_32bit_intbig.py.exp new file mode 100644 index 0000000000..d1fc1fe350 --- /dev/null +++ b/tests/extmod/uctypes_32bit_intbig.py.exp @@ -0,0 +1,11 @@ +b'\xff\xff\xff\x7f5678abcd' +b'\x00\x00\x00\x805678abcd' +b'\x03\x02\x01\xff5678abcd' +b'\x03\x02\x01\xff\x00\x00\x00\x80\x00\x00\x00\x00' +b'\x03\x02\x01\xff\x00\x00\x00\x00\x01\x00\x00\x00' += +b'\x7f\xff\xff\xff5678abcd' +b'\x80\x00\x00\x005678abcd' +b'\xff\x01\x02\x035678abcd' +b'\xff\x01\x02\x03\x00\x00\x00\x00\x80\x00\x00\x00' +b'\xff\x01\x02\x03\x00\x00\x00\x01\x00\x00\x00\x00'