In python Source code, the int object creation method PyInt_FromLong
, python create a new PyIntObject at the position of free_list's first element pointing to.
Here is the code:
PyObject *
PyInt_FromLong(long ival)
{
register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
return (PyObject *) v;
}
#endif
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
/* Inline PyObject_New */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
and Py_TYPE is:
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
How does free_list = (PyIntObject *)Py_TYPE(v);
work?
It move free_list to point to next object in list.
I think Py_TYPE(v)
will return PyInt_Type
, then (PyIntObject *)PyInt_Type
won't be the next object.
This behavior described in the comment on the top of the file:
free_list
is a singly-linked list of availablePyIntObjects
, linked via abuse of theirob_type
members.
You could also take a look into fill_free_list
function, which allocates PyIntObject
s according to the header comment:
static PyIntObject *
fill_free_list(void)
{
PyIntObject *p, *q;
/* Python's object allocator isn't appropriate for large blocks. */
p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
if (p == NULL)
return (PyIntObject *) PyErr_NoMemory();
((PyIntBlock *)p)->next = block_list;
block_list = (PyIntBlock *)p;
/* Link the int objects together, from rear to front, then return
the address of the last int object in the block. */
p = &((PyIntBlock *)p)->objects[0];
q = p + N_INTOBJECTS;
while (--q > p)
Py_TYPE(q) = (struct _typeobject *)(q-1);
Py_TYPE(q) = NULL;
return p + N_INTOBJECTS - 1;
}
The main line is Py_TYPE(q) = (struct _typeobject *)(q-1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With