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);
60#if PYTHON_VERSION >= 0x3e0
61 PyListObject *result_list = (PyListObject *)Nuitka_PyFreeList_Pop(&Nuitka_Py_freelists_GET(tstate)->lists);
63 if (result_list == NULL) {
64 result_list = (PyListObject *)Nuitka_GC_New(&PyList_Type);
66 Nuitka_Py_NewReference((PyObject *)result_list);
70#if PYTHON_VERSION < 0x3d0
71 PyListObject **items = tstate->interp->list.free_list;
72 int *numfree = &tstate->interp->list.numfree;
74 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
75 struct _Py_list_freelist *state = &freelists->lists;
76 PyListObject **items = state->items;
77 int *numfree = &state->numfree;
79 assert(*numfree >= 0);
80 PyListObject *result_list;
84 result_list = items[*numfree];
86 Nuitka_Py_NewReference((PyObject *)result_list);
88 result_list = (PyListObject *)Nuitka_GC_New(&PyList_Type);
91 assert(result_list != NULL);
92 assert(PyList_CheckExact(result_list));
97 _PyListArray *list_array = Nuitka_AllocateListArray(size);
99 if (unlikely(list_array == NULL)) {
100 Py_DECREF(result_list);
101 return PyErr_NoMemory();
104 memset(list_array->ob_item, 0, size *
sizeof(PyObject *));
105 result_list->ob_item = list_array->ob_item;
107 result_list->ob_item = (PyObject **)NuitkaMem_Calloc(size,
sizeof(PyObject *));
109 if (unlikely(result_list->ob_item == NULL)) {
110 Py_DECREF(result_list);
111 return PyErr_NoMemory();
115 result_list->ob_item = NULL;
118 Py_SET_SIZE(result_list, size);
119 result_list->allocated = size;
121 Nuitka_GC_Track(result_list);
123 return (PyObject *)result_list;
128PyObject *LIST_COPY(PyThreadState *tstate, PyObject *list) {
130 assert(PyList_CheckExact(list));
132 Py_ssize_t size = PyList_GET_SIZE(list);
133 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
135 if (unlikely(result == NULL)) {
139 for (Py_ssize_t i = 0; i < size; i++) {
140 PyObject *item = PyList_GET_ITEM(list, i);
142 PyList_SET_ITEM(result, i, item);
148static bool LIST_RESIZE(PyListObject *list, Py_ssize_t new_size) {
150 assert(new_size >= 0);
152 Py_ssize_t allocated = list->allocated;
154 if (allocated >= new_size && new_size >= (allocated >> 1)) {
155 Py_SET_SIZE(list, new_size);
160 size_t new_allocated;
165 new_allocated = ((size_t)new_size + (new_size >> 3) + 6) & ~(
size_t)3;
166 assert(new_allocated >= (
size_t)new_size);
169#ifdef Py_GIL_DISABLED
170 _PyListArray *array = Nuitka_AllocateListArray(new_allocated);
176 PyObject **old_items = list->ob_item;
177 if (list->ob_item != NULL) {
178 size_t num_allocated_bytes;
179 if (new_allocated < (
size_t)allocated) {
180 num_allocated_bytes = new_allocated *
sizeof(PyObject *);
182 num_allocated_bytes = allocated *
sizeof(PyObject *);
184 memcpy(array->ob_item, list->ob_item, num_allocated_bytes);
186 if (new_allocated > (
size_t)allocated) {
187 memset(array->ob_item + allocated, 0,
sizeof(PyObject *) * (new_allocated - allocated));
189 _Py_atomic_store_ptr_release(&list->ob_item, &array->ob_item);
190 list->allocated = new_allocated;
191 Py_SET_SIZE(list, new_size);
192 if (old_items != NULL) {
193 Nuitka_FreeListArray(old_items, _PyObject_GC_IS_SHARED(list));
196 size_t num_allocated_bytes = new_allocated *
sizeof(PyObject *);
199 PyObject **items = (PyObject **)NuitkaMem_Realloc(list->ob_item, num_allocated_bytes);
200 if (unlikely(items == NULL)) {
205 list->ob_item = items;
206 Py_SET_SIZE(list, new_size);
207 list->allocated = new_allocated;
213bool LIST_EXTEND_FROM_LIST(PyObject *list, PyObject *other) {
214#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
215 PyObject *result = _PyList_Extend((PyListObject *)list, other);
216 if (result != NULL) {
223 assert(PyList_CheckExact(list));
224 assert(PyList_CheckExact(other));
226 size_t n = PyList_GET_SIZE(other);
232 size_t m = Py_SIZE(list);
234 if (LIST_RESIZE((PyListObject *)list, m + n) ==
false) {
238 PyObject **src = &PyList_GET_ITEM(other, 0);
239 PyObject **dest = &PyList_GET_ITEM(list, m);
241 for (
size_t i = 0; i < n; i++) {
242 PyObject *o = src[i];
252bool LIST_EXTEND_FROM_ITERABLE(PyThreadState *tstate, PyObject *target, PyObject *other) {
253 CHECK_OBJECT(target);
254 assert(PyList_CheckExact(target));
258 PyListObject *list = (PyListObject *)target;
260#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
261 PyObject *result = _PyList_Extend(list, other);
262 if (result != NULL) {
274 if (PyList_CheckExact(other)) {
275 src = _PyList_ITEMS(other);
276 src_size = PyList_GET_SIZE(other);
277 }
else if (PyTuple_CheckExact(other)) {
278 src = _PyTuple_ITEMS(other);
279 src_size = PyTuple_GET_SIZE(other);
282#ifndef __NUITKA_NO_ASSERT__
292 Py_ssize_t list_size = PyList_GET_SIZE(list);
295 assert(list_size <= PY_SSIZE_T_MAX - src_size);
296 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
300 PyObject **target_items = _PyList_ITEMS(list) + list_size;
302 for (Py_ssize_t i = 0; i < src_size; i++) {
303 PyObject *value = src[i];
305 *target_items++ = value;
312 PyObject *iter = MAKE_ITERATOR(tstate, other);
317 PyObject *(*iternext)(PyObject *) = *Py_TYPE(iter)->tp_iternext;
319 Py_ssize_t cur_size = PyList_GET_SIZE(list);
321#if PYTHON_VERSION >= 0x300
323 src_size = PyObject_LengthHint(other, 8);
330 Py_ssize_t list_size = PyList_GET_SIZE(list);
332 if (list_size > PY_SSIZE_T_MAX - src_size) {
336 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
342 Py_SET_SIZE(list, list_size);
347 PyObject *item = iternext(iter);
350 bool stop_iteration_error = CHECK_AND_CLEAR_STOP_ITERATION_OCCURRED(tstate);
354 if (unlikely(stop_iteration_error ==
false)) {
355 if (cur_size < list->allocated) {
356 if (LIST_RESIZE(list, cur_size) ==
false) {
369 if (cur_size < list->allocated) {
371 PyList_SET_ITEM(list, cur_size, item);
372 Py_SET_SIZE(list, cur_size + 1);
374 assert(cur_size != PY_SSIZE_T_MAX);
376 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
380 PyList_SET_ITEM(list, cur_size, item);
386 assert(cur_size == PyList_GET_SIZE(list));
388 if (cur_size < list->allocated) {
389 if (LIST_RESIZE(list, cur_size) ==
false) {
398#if PYTHON_VERSION >= 0x390
399bool LIST_EXTEND_FOR_UNPACK(PyThreadState *tstate, PyObject *list, PyObject *other) {
402 bool result = LIST_EXTEND_FROM_ITERABLE(tstate, list, other);
404 if (likely(result)) {
408 PyObject *error = GET_ERROR_OCCURRED(tstate);
410 assert(error != NULL);
412 if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, error, PyExc_TypeError) &&
413 (Py_TYPE(other)->tp_iter == NULL && !PySequence_Check(other))) {
414 CLEAR_ERROR_OCCURRED(tstate);
415 PyErr_Format(PyExc_TypeError,
"Value after * must be an iterable, not %s", Py_TYPE(other)->tp_name);
422bool LIST_APPEND1(PyObject *target, PyObject *item) {
423 CHECK_OBJECT(target);
424 assert(PyList_CheckExact(target));
428#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
429 int res = PyList_Append(target, item);
433 PyListObject *list = (PyListObject *)target;
435 Py_ssize_t cur_size = PyList_GET_SIZE(list);
438 assert(cur_size <= PY_SSIZE_T_MAX);
440 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
444 PyList_SET_ITEM(list, cur_size, item);
450bool LIST_APPEND0(PyObject *target, PyObject *item) {
451 CHECK_OBJECT(target);
452 assert(PyList_CheckExact(target));
456#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
457 int res = PyList_Append(target, item);
460 PyListObject *list = (PyListObject *)target;
462 Py_ssize_t cur_size = PyList_GET_SIZE(list);
465 assert(cur_size <= PY_SSIZE_T_MAX);
467 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
471 PyList_SET_ITEM0(list, cur_size, item);
477bool LIST_REMOVE(PyObject *target, PyObject *item) {
478 CHECK_OBJECT(target);
479 assert(PyList_CheckExact(target));
483#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT && 0
485 int res = PyList_Remove(target, item);
488 PyListObject *list = (PyListObject *)target;
490 Py_ssize_t cur_size = PyList_GET_SIZE(list);
492 for (Py_ssize_t i = 0; i < cur_size; i++) {
493 PyObject *element = list->ob_item[i];
496 nuitka_bool cmp = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
499 if (cmp == NUITKA_BOOL_TRUE) {
501 Py_SET_SIZE(list, cur_size - 1);
503 memmove(list->ob_item + i, list->ob_item + i + 1,
sizeof(PyObject *) * (cur_size - i - 1));
506 }
else if (unlikely(cmp == NUITKA_BOOL_EXCEPTION)) {
511 PyThreadState *tstate = PyThreadState_GET();
513 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError,
"list.remove(x): x not in list");
518void LIST_CLEAR(PyObject *target) {
519 CHECK_OBJECT(target);
520 assert(PyList_CheckExact(target));
522 PyListObject *list = (PyListObject *)target;
524 PyObject **items = list->ob_item;
528 Py_ssize_t i = Py_SIZE(list);
529 Py_SET_SIZE(list, 0);
530 list->ob_item = NULL;
534 Py_XDECREF(items[i]);
541PyObject *getListIndexObject(Py_ssize_t value) {
542#if PYTHON_VERSION < 0x300
543 return PyInt_FromSsize_t(value);
547 return Nuitka_LongFromCLong((
long)value);
551PyObject *LIST_COUNT(PyObject *list, PyObject *item) {
553 assert(PyList_CheckExact(list));
555 Py_ssize_t count = 0;
557 for (Py_ssize_t i = 0; i < Py_SIZE(list); i++) {
558 PyObject *element = PyList_GET_ITEM(list, i);
561 if (element == item) {
570 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
573 if (nbool_res == NUITKA_BOOL_TRUE) {
579 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
584 return getListIndexObject(count);
587static PyObject *_LIST_INDEX_COMMON(PyThreadState *tstate, PyListObject *list, PyObject *item, Py_ssize_t start,
591 start += Py_SIZE(list);
599 stop += Py_SIZE(list);
606 for (Py_ssize_t i = start; i < stop && i < Py_SIZE(list); i++) {
607 PyObject *element = list->ob_item[i];
610 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
613 if (nbool_res == NUITKA_BOOL_TRUE) {
614 return getListIndexObject(i);
618 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
623#if PYTHON_VERSION < 0x300
624 PyObject *err_format = PyString_FromString(
"%r is not in list");
625 PyObject *format_tuple = MAKE_TUPLE1_0(tstate, item);
626 PyObject *err_string = PyString_Format(err_format, format_tuple);
627 Py_DECREF(format_tuple);
629 if (err_string == NULL) {
633 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_ValueError, err_string);
636 PyErr_Format(PyExc_ValueError,
"%R is not in list", item);
641PyObject *LIST_INDEX2(PyThreadState *tstate, PyObject *list, PyObject *item) {
643 assert(PyList_CheckExact(list));
645 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, 0, Py_SIZE(list));
648PyObject *LIST_INDEX3(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start) {
650 assert(PyList_CheckExact(list));
652 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
654 if (unlikely(start_index == NULL)) {
656 CLEAR_ERROR_OCCURRED(tstate);
658 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
659 "slice indices must be integers or have an __index__ method");
663 Py_ssize_t start_ssize;
664#if PYTHON_VERSION < 0x300
665 if (PyInt_CheckExact(start_index)) {
666 start_ssize = PyInt_AS_LONG(start_index);
668 start_ssize = PyLong_AsSsize_t(start_index);
671 start_ssize = PyLong_AsSsize_t(start_index);
674 Py_DECREF(start_index);
676 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, Py_SIZE(list));
679PyObject *LIST_INDEX4(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start, PyObject *stop) {
681 assert(PyList_CheckExact(list));
683 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
685 if (unlikely(start_index == NULL)) {
686 CLEAR_ERROR_OCCURRED(tstate);
688 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
689 "slice indices must be integers or have an __index__ method");
693 Py_ssize_t start_ssize;
694#if PYTHON_VERSION < 0x300
695 if (PyInt_CheckExact(start_index)) {
696 start_ssize = PyInt_AS_LONG(start_index);
698 start_ssize = PyLong_AsSsize_t(start_index);
701 start_ssize = PyLong_AsSsize_t(start_index);
704 Py_DECREF(start_index);
706 PyObject *stop_index = Nuitka_Number_IndexAsLong(stop);
708 if (unlikely(stop_index == NULL)) {
709 Py_DECREF(start_index);
711 CLEAR_ERROR_OCCURRED(tstate);
713 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
714 "slice indices must be integers or have an __index__ method");
718 Py_ssize_t stop_ssize;
719#if PYTHON_VERSION < 0x300
720 if (PyInt_CheckExact(stop_index)) {
721 stop_ssize = PyInt_AS_LONG(stop_index);
723 stop_ssize = PyLong_AsSsize_t(stop_index);
726 stop_ssize = PyLong_AsSsize_t(stop_index);
729 Py_DECREF(stop_index);
731 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, stop_ssize);
734bool LIST_INSERT(PyThreadState *tstate, PyObject *list, PyObject *index, PyObject *item) {
736 assert(PyList_CheckExact(list));
742 PyObject *index_long = Nuitka_Number_IndexAsLong(index);
744 if (unlikely(index_long == NULL)) {
745 CLEAR_ERROR_OCCURRED(tstate);
747 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
"'%s' cannot be interpreted as an integer", index);
751 Py_ssize_t index_ssize;
752#if PYTHON_VERSION < 0x300
753 if (PyInt_CheckExact(index_long)) {
754 index_ssize = PyInt_AS_LONG(index_long);
756 index_ssize = PyLong_AsSsize_t(index_long);
759 index_ssize = PyLong_AsSsize_t(index_long);
762 Py_DECREF(index_long);
764 LIST_INSERT_CONST(list, index_ssize, item);
768void LIST_INSERT_CONST(PyObject *list, Py_ssize_t index, PyObject *item) {
770 assert(PyList_CheckExact(list));
773 PyListObject *list_object = (PyListObject *)list;
775 Py_ssize_t n = Py_SIZE(list_object);
778 if (LIST_RESIZE(list_object, n + 1) ==
false) {
794 PyObject **items = list_object->ob_item;
796 for (Py_ssize_t i = n; --i >= index;) {
797 items[i + 1] = items[i];
804static void _Nuitka_ReverseObjectsSlice(PyObject **lo, PyObject **hi) {
805 assert(lo != NULL && hi != NULL);
821void LIST_REVERSE(PyObject *list) {
823 assert(PyList_CheckExact(list));
825 PyListObject *list_object = (PyListObject *)list;
827 if (Py_SIZE(list_object) > 1) {
828 _Nuitka_ReverseObjectsSlice(list_object->ob_item, list_object->ob_item + Py_SIZE(list_object));
832#if PYTHON_VERSION >= 0x300 && !defined(_NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT)
833static bool allocateListItems(PyListObject *list, Py_ssize_t size) {
834 PyObject **items = PyMem_New(PyObject *, size);
836 if (unlikely(items == NULL)) {
841 list->ob_item = items;
842 list->allocated = size;
849PyObject *MAKE_LIST(PyThreadState *tstate, PyObject *iterable) {
852 PyObject *list = MAKE_LIST_EMPTY(tstate, 0);
854#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
855 PyObject *result = _PyList_Extend((PyListObject *)list, iterable);
856 if (result == NULL) {
866#if PYTHON_VERSION >= 0x300
867 if (Nuitka_PyObject_HasLen(iterable)) {
868 Py_ssize_t iter_len = Nuitka_PyObject_Size(iterable);
870 if (unlikely(iter_len == -1)) {
871 if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
875 CLEAR_ERROR_OCCURRED(tstate);
879 if (allocateListItems((PyListObject *)list, iter_len) ==
false) {
886 bool res = LIST_EXTEND_FROM_ITERABLE(tstate, list, iterable);
890 if (unlikely(res ==
false)) {
899#include "HelpersListsGenerated.c"