[Python-3000] longobject.c and Windows x64

Trent Nelson tnelson at onresolve.com
Mon Apr 14 12:02:18 CEST 2008


On Windows x64, sizeof(size_t) > sizeof(long), so the existing PyLong_FromSsize_t and PyLong_FromSize_t implementations in longobject.c are just plain wrong.  I've patched it as follows, but as I'm not well versed in the many intricacies of longobject.c, I'd appreciate input from others.

As far as I can tell, we can use FromLong or FromLongLong (and their unsigned counterparts) exclusively; I don't see why we'd need to rely on _PyLong_FromByteArray as our incoming ival is never going to be larger than an ssize_t|size_t.  (The _PyLong_FromByteArray is intended for incoming numbers that we don't know the size of up front, right?)

Index: longobject.c
===================================================================
--- longobject.c        (revision 62292)
+++ longobject.c        (working copy)
@@ -1099,13 +1099,13 @@
 PyObject *
 PyLong_FromSsize_t(Py_ssize_t ival)
 {
-       Py_ssize_t bytes = ival;
-       int one = 1;
-       if (ival < PyLong_BASE)
-               return PyLong_FromLong(ival);
-       return _PyLong_FromByteArray(
-                       (unsigned char *)&bytes,
-                       SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+       return PyLong_FromLongLong(ival);
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+       return PyLong_FromLong(ival);
+#else
+#error "Expected SIZEOF_SIZE_T to equal SIZEOF_LONG_LONG or SIZEOF_LONG"
+#endif
 }

 /* Create a new long int object from a C size_t. */
@@ -1113,13 +1113,13 @@
 PyObject *
 PyLong_FromSize_t(size_t ival)
 {
-       size_t bytes = ival;
-       int one = 1;
-       if (ival < PyLong_BASE)
-               return PyLong_FromLong(ival);
-       return _PyLong_FromByteArray(
-                       (unsigned char *)&bytes,
-                       SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+       return PyLong_FromUnsignedLongLong(ival);
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+       return PyLong_FromUnsignedLong(ival);
+#else
+#error "Expected SIZEOF_SIZE_T to equal SIZEOF_LONG_LONG or SIZEOF_LONG"
+#endif
 }

 /* Get a C PY_LONG_LONG int from a long int object.


More information about the Python-3000 mailing list