10#include "nuitka/prelude.h"
15static PyObject *Nuitka_LongFromCLong(
long ival);
23static _PyListArray *Nuitka_AllocateListArray(
size_t capacity) {
24 if (unlikely(capacity > PY_SSIZE_T_MAX /
sizeof(PyObject *) - 1)) {
29 _PyListArray *list_array = PyMem_Malloc(
sizeof(_PyListArray) + capacity *
sizeof(PyObject *));
31 if (unlikely(list_array == NULL)) {
35 list_array->allocated = capacity;
40static void Nuitka_FreeListArray(PyObject **items,
bool use_qsbr) {
41 _PyListArray *array = _Py_CONTAINER_OF(items, _PyListArray, ob_item);
44 NuitkaMem_FreeDelayed(array);
46 NuitkaMem_Free(array);
52#if NUITKA_LIST_HAS_FREELIST
54PyObject *MAKE_LIST_EMPTY(PyThreadState *tstate, Py_ssize_t size) {
57#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
58 return PyList_New(size);
62#if PYTHON_VERSION < 0x3d0
63 PyListObject **items = tstate->interp->list.free_list;
64 int *numfree = &tstate->interp->list.numfree;
66 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
67 struct _Py_list_freelist *state = &freelists->lists;
68 PyListObject **items = state->items;
69 int *numfree = &state->numfree;
71 assert(*numfree >= 0);
72 PyListObject *result_list;
76 result_list = items[*numfree];
78 Nuitka_Py_NewReference((PyObject *)result_list);
80 result_list = (PyListObject *)Nuitka_GC_New(&PyList_Type);
86 _PyListArray *list_array = Nuitka_AllocateListArray(size);
88 if (unlikely(list_array == NULL)) {
89 Py_DECREF(result_list);
90 return PyErr_NoMemory();
93 result_list->ob_item = (PyObject **)NuitkaMem_Calloc(size,
sizeof(PyObject *));
95 if (unlikely(result_list->ob_item == NULL)) {
96 Py_DECREF(result_list);
97 return PyErr_NoMemory();
101 result_list->ob_item = NULL;
104 Py_SET_SIZE(result_list, size);
105 result_list->allocated = size;
107 Nuitka_GC_Track(result_list);
109 return (PyObject *)result_list;
114PyObject *LIST_COPY(PyThreadState *tstate, PyObject *list) {
116 assert(PyList_CheckExact(list));
118 Py_ssize_t size = PyList_GET_SIZE(list);
119 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
121 if (unlikely(result == NULL)) {
125 for (Py_ssize_t i = 0; i < size; i++) {
126 PyObject *item = PyList_GET_ITEM(list, i);
128 PyList_SET_ITEM(result, i, item);
134static bool LIST_RESIZE(PyListObject *list, Py_ssize_t new_size) {
136 assert(new_size >= 0);
138 Py_ssize_t allocated = list->allocated;
140 if (allocated >= new_size && new_size >= (allocated >> 1)) {
141 Py_SET_SIZE(list, new_size);
146 size_t new_allocated;
151 new_allocated = ((size_t)new_size + (new_size >> 3) + 6) & ~(
size_t)3;
152 assert(new_allocated >= (
size_t)new_size);
155#ifdef Py_GIL_DISABLED
156 _PyListArray *array = Nuitka_AllocateListArray(new_allocated);
162 PyObject **old_items = list->ob_item;
163 if (list->ob_item != NULL) {
164 size_t num_allocated_bytes;
165 if (new_allocated < (
size_t)allocated) {
166 num_allocated_bytes = new_allocated *
sizeof(PyObject *);
168 num_allocated_bytes = allocated *
sizeof(PyObject *);
170 memcpy(array->ob_item, list->ob_item, num_allocated_bytes);
172 if (new_allocated > (
size_t)allocated) {
173 memset(array->ob_item + allocated, 0,
sizeof(PyObject *) * (new_allocated - allocated));
175 _Py_atomic_store_ptr_release(&list->ob_item, &array->ob_item);
176 list->allocated = new_allocated;
177 Py_SET_SIZE(list, new_size);
178 if (old_items != NULL) {
179 Nuitka_FreeListArray(old_items, _PyObject_GC_IS_SHARED(list));
182 size_t num_allocated_bytes = new_allocated *
sizeof(PyObject *);
185 PyObject **items = (PyObject **)NuitkaMem_Realloc(list->ob_item, num_allocated_bytes);
186 if (unlikely(items == NULL)) {
191 list->ob_item = items;
192 Py_SET_SIZE(list, new_size);
193 list->allocated = new_allocated;
199bool LIST_EXTEND_FROM_LIST(PyObject *list, PyObject *other) {
200#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
201 PyObject *result = _PyList_Extend((PyListObject *)list, other);
202 if (result != NULL) {
209 assert(PyList_CheckExact(list));
210 assert(PyList_CheckExact(other));
212 size_t n = PyList_GET_SIZE(other);
218 size_t m = Py_SIZE(list);
220 if (LIST_RESIZE((PyListObject *)list, m + n) ==
false) {
224 PyObject **src = &PyList_GET_ITEM(other, 0);
225 PyObject **dest = &PyList_GET_ITEM(list, m);
227 for (
size_t i = 0; i < n; i++) {
228 PyObject *o = src[i];
238bool LIST_EXTEND_FROM_ITERABLE(PyThreadState *tstate, PyObject *target, PyObject *other) {
239 CHECK_OBJECT(target);
240 assert(PyList_CheckExact(target));
244 PyListObject *list = (PyListObject *)target;
246#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
247 PyObject *result = _PyList_Extend(list, other);
248 if (result != NULL) {
260 if (PyList_CheckExact(other)) {
261 src = _PyList_ITEMS(other);
262 src_size = PyList_GET_SIZE(other);
263 }
else if (PyTuple_CheckExact(other)) {
264 src = _PyTuple_ITEMS(other);
265 src_size = PyTuple_GET_SIZE(other);
268#ifndef __NUITKA_NO_ASSERT__
278 Py_ssize_t list_size = PyList_GET_SIZE(list);
281 assert(list_size <= PY_SSIZE_T_MAX - src_size);
282 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
286 PyObject **target_items = _PyList_ITEMS(list) + list_size;
288 for (Py_ssize_t i = 0; i < src_size; i++) {
289 PyObject *value = src[i];
291 *target_items++ = value;
298 PyObject *iter = MAKE_ITERATOR(tstate, other);
303 PyObject *(*iternext)(PyObject *) = *Py_TYPE(iter)->tp_iternext;
305 Py_ssize_t cur_size = PyList_GET_SIZE(list);
307#if PYTHON_VERSION >= 0x300
309 src_size = PyObject_LengthHint(other, 8);
316 Py_ssize_t list_size = PyList_GET_SIZE(list);
318 if (list_size > PY_SSIZE_T_MAX - src_size) {
322 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
328 Py_SET_SIZE(list, list_size);
333 PyObject *item = iternext(iter);
336 bool stop_iteration_error = CHECK_AND_CLEAR_STOP_ITERATION_OCCURRED(tstate);
340 if (unlikely(stop_iteration_error ==
false)) {
341 if (cur_size < list->allocated) {
342 if (LIST_RESIZE(list, cur_size) ==
false) {
355 if (cur_size < list->allocated) {
357 PyList_SET_ITEM(list, cur_size, item);
358 Py_SET_SIZE(list, cur_size + 1);
360 assert(cur_size != PY_SSIZE_T_MAX);
362 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
366 PyList_SET_ITEM(list, cur_size, item);
372 assert(cur_size == PyList_GET_SIZE(list));
374 if (cur_size < list->allocated) {
375 if (LIST_RESIZE(list, cur_size) ==
false) {
384#if PYTHON_VERSION >= 0x390
385bool LIST_EXTEND_FOR_UNPACK(PyThreadState *tstate, PyObject *list, PyObject *other) {
388 bool result = LIST_EXTEND_FROM_ITERABLE(tstate, list, other);
390 if (likely(result)) {
394 PyObject *error = GET_ERROR_OCCURRED(tstate);
396 assert(error != NULL);
398 if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, error, PyExc_TypeError) &&
399 (Py_TYPE(other)->tp_iter == NULL && !PySequence_Check(other))) {
400 CLEAR_ERROR_OCCURRED(tstate);
401 PyErr_Format(PyExc_TypeError,
"Value after * must be an iterable, not %s", Py_TYPE(other)->tp_name);
408bool LIST_APPEND1(PyObject *target, PyObject *item) {
409 CHECK_OBJECT(target);
410 assert(PyList_CheckExact(target));
414#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
415 int res = PyList_Append(target, item);
419 PyListObject *list = (PyListObject *)target;
421 Py_ssize_t cur_size = PyList_GET_SIZE(list);
424 assert(cur_size <= PY_SSIZE_T_MAX);
426 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
430 PyList_SET_ITEM(list, cur_size, item);
436bool LIST_APPEND0(PyObject *target, PyObject *item) {
437 CHECK_OBJECT(target);
438 assert(PyList_CheckExact(target));
442#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
443 int res = PyList_Append(target, item);
446 PyListObject *list = (PyListObject *)target;
448 Py_ssize_t cur_size = PyList_GET_SIZE(list);
451 assert(cur_size <= PY_SSIZE_T_MAX);
453 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
457 PyList_SET_ITEM0(list, cur_size, item);
463bool LIST_REMOVE(PyObject *target, PyObject *item) {
464 CHECK_OBJECT(target);
465 assert(PyList_CheckExact(target));
469#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT && 0
471 int res = PyList_Remove(target, item);
474 PyListObject *list = (PyListObject *)target;
476 Py_ssize_t cur_size = PyList_GET_SIZE(list);
478 for (Py_ssize_t i = 0; i < cur_size; i++) {
479 PyObject *element = list->ob_item[i];
482 nuitka_bool cmp = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
485 if (cmp == NUITKA_BOOL_TRUE) {
487 Py_SET_SIZE(list, cur_size - 1);
489 memmove(list->ob_item + i, list->ob_item + i + 1,
sizeof(PyObject *) * (cur_size - i - 1));
492 }
else if (unlikely(cmp == NUITKA_BOOL_EXCEPTION)) {
497 PyThreadState *tstate = PyThreadState_GET();
499 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError,
"list.remove(x): x not in list");
504void LIST_CLEAR(PyObject *target) {
505 CHECK_OBJECT(target);
506 assert(PyList_CheckExact(target));
508 PyListObject *list = (PyListObject *)target;
510 PyObject **items = list->ob_item;
514 Py_ssize_t i = Py_SIZE(list);
515 Py_SET_SIZE(list, 0);
516 list->ob_item = NULL;
520 Py_XDECREF(items[i]);
527PyObject *getListIndexObject(Py_ssize_t value) {
528#if PYTHON_VERSION < 0x300
529 return PyInt_FromSsize_t(value);
533 return Nuitka_LongFromCLong((
long)value);
537PyObject *LIST_COUNT(PyObject *list, PyObject *item) {
539 assert(PyList_CheckExact(list));
541 Py_ssize_t count = 0;
543 for (Py_ssize_t i = 0; i < Py_SIZE(list); i++) {
544 PyObject *element = PyList_GET_ITEM(list, i);
547 if (element == item) {
556 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
559 if (nbool_res == NUITKA_BOOL_TRUE) {
565 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
570 return getListIndexObject(count);
573static PyObject *_LIST_INDEX_COMMON(PyThreadState *tstate, PyListObject *list, PyObject *item, Py_ssize_t start,
577 start += Py_SIZE(list);
585 stop += Py_SIZE(list);
592 for (Py_ssize_t i = start; i < stop && i < Py_SIZE(list); i++) {
593 PyObject *element = list->ob_item[i];
596 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
599 if (nbool_res == NUITKA_BOOL_TRUE) {
600 return getListIndexObject(i);
604 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
609#if PYTHON_VERSION < 0x300
610 PyObject *err_format = PyString_FromString(
"%r is not in list");
611 PyObject *format_tuple = MAKE_TUPLE1_0(tstate, item);
612 PyObject *err_string = PyString_Format(err_format, format_tuple);
613 Py_DECREF(format_tuple);
615 if (err_string == NULL) {
619 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_ValueError, err_string);
622 PyErr_Format(PyExc_ValueError,
"%R is not in list", item);
627PyObject *LIST_INDEX2(PyThreadState *tstate, PyObject *list, PyObject *item) {
629 assert(PyList_CheckExact(list));
631 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, 0, Py_SIZE(list));
634PyObject *LIST_INDEX3(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start) {
636 assert(PyList_CheckExact(list));
638 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
640 if (unlikely(start_index == NULL)) {
642 CLEAR_ERROR_OCCURRED(tstate);
644 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
645 "slice indices must be integers or have an __index__ method");
649 Py_ssize_t start_ssize;
650#if PYTHON_VERSION < 0x300
651 if (PyInt_CheckExact(start_index)) {
652 start_ssize = PyInt_AS_LONG(start_index);
654 start_ssize = PyLong_AsSsize_t(start_index);
657 start_ssize = PyLong_AsSsize_t(start_index);
660 Py_DECREF(start_index);
662 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, Py_SIZE(list));
665PyObject *LIST_INDEX4(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start, PyObject *stop) {
667 assert(PyList_CheckExact(list));
669 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
671 if (unlikely(start_index == NULL)) {
672 CLEAR_ERROR_OCCURRED(tstate);
674 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
675 "slice indices must be integers or have an __index__ method");
679 Py_ssize_t start_ssize;
680#if PYTHON_VERSION < 0x300
681 if (PyInt_CheckExact(start_index)) {
682 start_ssize = PyInt_AS_LONG(start_index);
684 start_ssize = PyLong_AsSsize_t(start_index);
687 start_ssize = PyLong_AsSsize_t(start_index);
690 Py_DECREF(start_index);
692 PyObject *stop_index = Nuitka_Number_IndexAsLong(stop);
694 if (unlikely(stop_index == NULL)) {
695 Py_DECREF(start_index);
697 CLEAR_ERROR_OCCURRED(tstate);
699 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
700 "slice indices must be integers or have an __index__ method");
704 Py_ssize_t stop_ssize;
705#if PYTHON_VERSION < 0x300
706 if (PyInt_CheckExact(stop_index)) {
707 stop_ssize = PyInt_AS_LONG(stop_index);
709 stop_ssize = PyLong_AsSsize_t(stop_index);
712 stop_ssize = PyLong_AsSsize_t(stop_index);
715 Py_DECREF(stop_index);
717 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, stop_ssize);
720bool LIST_INSERT(PyThreadState *tstate, PyObject *list, PyObject *index, PyObject *item) {
722 assert(PyList_CheckExact(list));
728 PyObject *index_long = Nuitka_Number_IndexAsLong(index);
730 if (unlikely(index_long == NULL)) {
731 CLEAR_ERROR_OCCURRED(tstate);
733 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
"'%s' cannot be interpreted as an integer", index);
737 Py_ssize_t index_ssize;
738#if PYTHON_VERSION < 0x300
739 if (PyInt_CheckExact(index_long)) {
740 index_ssize = PyInt_AS_LONG(index_long);
742 index_ssize = PyLong_AsSsize_t(index_long);
745 index_ssize = PyLong_AsSsize_t(index_long);
748 Py_DECREF(index_long);
750 LIST_INSERT_CONST(list, index_ssize, item);
754void LIST_INSERT_CONST(PyObject *list, Py_ssize_t index, PyObject *item) {
756 assert(PyList_CheckExact(list));
759 PyListObject *list_object = (PyListObject *)list;
761 Py_ssize_t n = Py_SIZE(list_object);
764 if (LIST_RESIZE(list_object, n + 1) ==
false) {
780 PyObject **items = list_object->ob_item;
782 for (Py_ssize_t i = n; --i >= index;) {
783 items[i + 1] = items[i];
790static void _Nuitka_ReverseObjectsSlice(PyObject **lo, PyObject **hi) {
791 assert(lo != NULL && hi != NULL);
807void LIST_REVERSE(PyObject *list) {
809 assert(PyList_CheckExact(list));
811 PyListObject *list_object = (PyListObject *)list;
813 if (Py_SIZE(list_object) > 1) {
814 _Nuitka_ReverseObjectsSlice(list_object->ob_item, list_object->ob_item + Py_SIZE(list_object));
818#if PYTHON_VERSION >= 0x300 && !defined(_NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT)
819static bool allocateListItems(PyListObject *list, Py_ssize_t size) {
820 PyObject **items = PyMem_New(PyObject *, size);
822 if (unlikely(items == NULL)) {
827 list->ob_item = items;
828 list->allocated = size;
835PyObject *MAKE_LIST(PyThreadState *tstate, PyObject *iterable) {
838 PyObject *list = MAKE_LIST_EMPTY(tstate, 0);
840#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
841 PyObject *result = _PyList_Extend((PyListObject *)list, iterable);
842 if (result == NULL) {
852#if PYTHON_VERSION >= 0x300
853 if (Nuitka_PyObject_HasLen(iterable)) {
854 Py_ssize_t iter_len = Nuitka_PyObject_Size(iterable);
856 if (unlikely(iter_len == -1)) {
857 if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
861 CLEAR_ERROR_OCCURRED(tstate);
865 if (allocateListItems((PyListObject *)list, iter_len) ==
false) {
872 bool res = LIST_EXTEND_FROM_ITERABLE(tstate, list, iterable);
876 if (unlikely(res ==
false)) {
885#include "HelpersListsGenerated.c"