From c69517267f5ac46677d64f5fad898f0cfbf37b3a Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 31 Oct 2025 02:16:12 +0000 Subject: [PATCH] More robust packing of flats in FF cache --- mypyc/lib-rt/librt_internal.c | 20 ++++++++++++++------ mypyc/test-data/run-classes.test | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/mypyc/lib-rt/librt_internal.c b/mypyc/lib-rt/librt_internal.c index 8599017c31a8..cbd447964203 100644 --- a/mypyc/lib-rt/librt_internal.c +++ b/mypyc/lib-rt/librt_internal.c @@ -448,14 +448,18 @@ write_bytes(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnam /* float format: - stored as a C double + stored using PyFloat helpers in little-endian format. */ static double read_float_internal(PyObject *data) { _CHECK_BUFFER(data, CPY_FLOAT_ERROR) - _CHECK_READ(data, sizeof(double), CPY_FLOAT_ERROR) - double res = _READ(data, double); + _CHECK_READ(data, 8, CPY_FLOAT_ERROR) + char *buf = ((BufferObject *)data)->buf; + double res = PyFloat_Unpack8(buf + ((BufferObject *)data)->pos, 1); + if (unlikely((res == -1.0) && PyErr_Occurred())) + return CPY_FLOAT_ERROR; + ((BufferObject *)data)->pos += 8; return res; } @@ -477,9 +481,13 @@ read_float(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwname static char write_float_internal(PyObject *data, double value) { _CHECK_BUFFER(data, CPY_NONE_ERROR) - _CHECK_SIZE(data, sizeof(double)) - _WRITE(data, double, value) - ((BufferObject *)data)->end += sizeof(double); + _CHECK_SIZE(data, 8) + char *buf = ((BufferObject *)data)->buf; + int res = PyFloat_Pack8(value, buf + ((BufferObject *)data)->pos, 1); + if (unlikely(res == -1)) + return CPY_NONE_ERROR; + ((BufferObject *)data)->pos += 8; + ((BufferObject *)data)->end += 8; return CPY_NONE; } diff --git a/mypyc/test-data/run-classes.test b/mypyc/test-data/run-classes.test index e08f2fd7007d..e44569630fec 100644 --- a/mypyc/test-data/run-classes.test +++ b/mypyc/test-data/run-classes.test @@ -2741,6 +2741,7 @@ def test_buffer_roundtrip() -> None: write_bytes(b, b"a" * 127) write_bytes(b, b"a" * 128) write_float(b, 0.1) + write_float(b, -1.0) write_float(b, -113.0) write_int(b, 0) write_int(b, 1) @@ -2766,6 +2767,7 @@ def test_buffer_roundtrip() -> None: assert read_bytes(b) == b"a" * 127 assert read_bytes(b) == b"a" * 128 assert read_float(b) == 0.1 + assert read_float(b) == -1.0 assert read_float(b) == -113.0 assert read_int(b) == 0 assert read_int(b) == 1