[Python-Dev] FW: 64-bit port of Python

Greg Stein gstein@lyra.org
Wed, 9 Feb 2000 06:12:47 -0800 (PST)

On Wed, 9 Feb 2000, Tim Peters wrote:
> [Trent Mick [mailto:trentm@ActiveState.com]]
> > A couple of example where I think the Python core does just that:
> Good eye, Trent!  Thank you.  I'm also sending this to Mark Hammond, since
> ActiveState now pays him to worry about Python's Windows story -- and
> perhaps pays you too <wink>.

In any case where Python needs to cast a pointer back/forth with an
"integer", there are two new routines in Python 1.5.2. From longobject.h:

extern DL_IMPORT(PyObject *) PyLong_FromVoidPtr Py_PROTO((void *));
extern DL_IMPORT(void *) PyLong_AsVoidPtr Py_PROTO((PyObject *));

I supplied the patch for these while I was also adding the 'P' format code
for the "struct" module.

The functions return a PyIntObject or a PyLongObject depending on whether
the size of void pointer matches the size of a C long value. If a pointer
fits in a long, you get an Integer. Otherwise, you get a Long.

> > "Modules/arraymodule.c::728":
> >
> >   static PyObject *
> >   array_buffer_info(self, args)
> >   	arrayobject *self;
> >   	PyObject *args;
> >   {
> >   	return Py_BuildValue("ll",
> >   			     (long)(self->ob_item), (long)(self->ob_size));
> >   }
> >
> > where 'ob_item' is a pointer.
> Yes, the author of the new buffer interface code is being shot for many
> reasons <wink>.

Yah. That function is quite insane. *shudder*

It should use PyLong_FromVoidPtr for the first item, and PyInt_FromLong
for the second (IMO, it is reasonable to assume ob_size fits in a C long).

However, I'd simply argue that the function should probably be punted.
What is it for?

> > "Python/bltinmodule.c::899":
> >
> >   static PyObject *
> >   builtin_id(self, args)
> > 	PyObject *self;
> > 	PyObject *args;
> >   {
> > 	PyObject *v;
> >
> > 	if (!PyArg_ParseTuple(args, "O:id", &v))
> > 		return NULL;
> > 	return PyInt_FromLong((long)v);
> >   }
> Oh yes.  Been there forever, and won't work at all (while nothing promises
> that id returns an address, it's crucial that "id(x) == id(y)" iff "x is y"
> in Python).

Assuming that we can say that id() is allowed to return a PyLongObject,
then this should just use PyLong_FromVoidPtr. On most platforms, it will
still return an Integer. For Win64 (and some other platforms), it will
return a Long.

> > This is evidenced by all the use of PyInt_FromLong() above. There are
> > no format specifiers in the PyArg_Parse*() and Py_BuildValue()
> > functions for converting a pointer. This was fine when 'long' would
> > do. On Win64 sizeof(long)==4 and size(void*)==8.

Similar to the structmodule, I might suggest adding a 'P' code. Exercise
for the reader...

However, I might counter that it is an uncommon operation, so I would
argue against adding the code. People that need to do this can resort to
manually using the PyLong_* functions.

> > If so, then the representation of the Python integer type will have
> > to change (i.e. the use of 'long' cannot be relied upon). One should
> > then carry through and change (or obselete) the *_AsLong(),
> > *_FromLong() Python/C API functions to becomesomething like
> > AsLargestNativeInt(), *_FromLargestNativeInt()  (or some
> > less bulky name).
> >
> > Alternatively, if the python integer type continues to use the C
> > 'long' type for 64-bit systems then the following ugly thing
> > happens:
> >  - A Python integer on a 64-bit Intel chip compiled with MSVC is
> >    32-bits wide.
> >  - A Python integer on a 64-bit Intel chip compiled with gcc is
> >    64-bits wide.
> > That cannot be good.

The problem already solved (it's so much fun to borrow Guido's time
machine!). Some of the C code just needs to catch up and use the new
functionality, though.

> ... other Tim remarks ...

Tim! Wake up! New functions snuck in behind your back! hehe...


Greg Stein, http://www.lyra.org/