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(&_Py_freelists_GET()->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 result_list->ob_item = (PyObject **)NuitkaMem_Calloc(size,
sizeof(PyObject *));
106 if (unlikely(result_list->ob_item == NULL)) {
107 Py_DECREF(result_list);
108 return PyErr_NoMemory();
112 result_list->ob_item = NULL;
115 Py_SET_SIZE(result_list, size);
116 result_list->allocated = size;
118 Nuitka_GC_Track(result_list);
120 return (PyObject *)result_list;
125PyObject *LIST_COPY(PyThreadState *tstate, PyObject *list) {
127 assert(PyList_CheckExact(list));
129 Py_ssize_t size = PyList_GET_SIZE(list);
130 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
132 if (unlikely(result == NULL)) {
136 for (Py_ssize_t i = 0; i < size; i++) {
137 PyObject *item = PyList_GET_ITEM(list, i);
139 PyList_SET_ITEM(result, i, item);
145static bool LIST_RESIZE(PyListObject *list, Py_ssize_t new_size) {
147 assert(new_size >= 0);
149 Py_ssize_t allocated = list->allocated;
151 if (allocated >= new_size && new_size >= (allocated >> 1)) {
152 Py_SET_SIZE(list, new_size);
157 size_t new_allocated;
162 new_allocated = ((size_t)new_size + (new_size >> 3) + 6) & ~(
size_t)3;
163 assert(new_allocated >= (
size_t)new_size);
166#ifdef Py_GIL_DISABLED
167 _PyListArray *array = Nuitka_AllocateListArray(new_allocated);
173 PyObject **old_items = list->ob_item;
174 if (list->ob_item != NULL) {
175 size_t num_allocated_bytes;
176 if (new_allocated < (
size_t)allocated) {
177 num_allocated_bytes = new_allocated *
sizeof(PyObject *);
179 num_allocated_bytes = allocated *
sizeof(PyObject *);
181 memcpy(array->ob_item, list->ob_item, num_allocated_bytes);
183 if (new_allocated > (
size_t)allocated) {
184 memset(array->ob_item + allocated, 0,
sizeof(PyObject *) * (new_allocated - allocated));
186 _Py_atomic_store_ptr_release(&list->ob_item, &array->ob_item);
187 list->allocated = new_allocated;
188 Py_SET_SIZE(list, new_size);
189 if (old_items != NULL) {
190 Nuitka_FreeListArray(old_items, _PyObject_GC_IS_SHARED(list));
193 size_t num_allocated_bytes = new_allocated *
sizeof(PyObject *);
196 PyObject **items = (PyObject **)NuitkaMem_Realloc(list->ob_item, num_allocated_bytes);
197 if (unlikely(items == NULL)) {
202 list->ob_item = items;
203 Py_SET_SIZE(list, new_size);
204 list->allocated = new_allocated;
210bool LIST_EXTEND_FROM_LIST(PyObject *list, PyObject *other) {
211#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
212 PyObject *result = _PyList_Extend((PyListObject *)list, other);
213 if (result != NULL) {
220 assert(PyList_CheckExact(list));
221 assert(PyList_CheckExact(other));
223 size_t n = PyList_GET_SIZE(other);
229 size_t m = Py_SIZE(list);
231 if (LIST_RESIZE((PyListObject *)list, m + n) ==
false) {
235 PyObject **src = &PyList_GET_ITEM(other, 0);
236 PyObject **dest = &PyList_GET_ITEM(list, m);
238 for (
size_t i = 0; i < n; i++) {
239 PyObject *o = src[i];
249bool LIST_EXTEND_FROM_ITERABLE(PyThreadState *tstate, PyObject *target, PyObject *other) {
250 CHECK_OBJECT(target);
251 assert(PyList_CheckExact(target));
255 PyListObject *list = (PyListObject *)target;
257#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
258 PyObject *result = _PyList_Extend(list, other);
259 if (result != NULL) {
271 if (PyList_CheckExact(other)) {
272 src = _PyList_ITEMS(other);
273 src_size = PyList_GET_SIZE(other);
274 }
else if (PyTuple_CheckExact(other)) {
275 src = _PyTuple_ITEMS(other);
276 src_size = PyTuple_GET_SIZE(other);
279#ifndef __NUITKA_NO_ASSERT__
289 Py_ssize_t list_size = PyList_GET_SIZE(list);
292 assert(list_size <= PY_SSIZE_T_MAX - src_size);
293 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
297 PyObject **target_items = _PyList_ITEMS(list) + list_size;
299 for (Py_ssize_t i = 0; i < src_size; i++) {
300 PyObject *value = src[i];
302 *target_items++ = value;
309 PyObject *iter = MAKE_ITERATOR(tstate, other);
314 PyObject *(*iternext)(PyObject *) = *Py_TYPE(iter)->tp_iternext;
316 Py_ssize_t cur_size = PyList_GET_SIZE(list);
318#if PYTHON_VERSION >= 0x300
320 src_size = PyObject_LengthHint(other, 8);
327 Py_ssize_t list_size = PyList_GET_SIZE(list);
329 if (list_size > PY_SSIZE_T_MAX - src_size) {
333 if (LIST_RESIZE(list, list_size + src_size) ==
false) {
339 Py_SET_SIZE(list, list_size);
344 PyObject *item = iternext(iter);
347 bool stop_iteration_error = CHECK_AND_CLEAR_STOP_ITERATION_OCCURRED(tstate);
351 if (unlikely(stop_iteration_error ==
false)) {
352 if (cur_size < list->allocated) {
353 if (LIST_RESIZE(list, cur_size) ==
false) {
366 if (cur_size < list->allocated) {
368 PyList_SET_ITEM(list, cur_size, item);
369 Py_SET_SIZE(list, cur_size + 1);
371 assert(cur_size != PY_SSIZE_T_MAX);
373 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
377 PyList_SET_ITEM(list, cur_size, item);
383 assert(cur_size == PyList_GET_SIZE(list));
385 if (cur_size < list->allocated) {
386 if (LIST_RESIZE(list, cur_size) ==
false) {
395#if PYTHON_VERSION >= 0x390
396bool LIST_EXTEND_FOR_UNPACK(PyThreadState *tstate, PyObject *list, PyObject *other) {
399 bool result = LIST_EXTEND_FROM_ITERABLE(tstate, list, other);
401 if (likely(result)) {
405 PyObject *error = GET_ERROR_OCCURRED(tstate);
407 assert(error != NULL);
409 if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, error, PyExc_TypeError) &&
410 (Py_TYPE(other)->tp_iter == NULL && !PySequence_Check(other))) {
411 CLEAR_ERROR_OCCURRED(tstate);
412 PyErr_Format(PyExc_TypeError,
"Value after * must be an iterable, not %s", Py_TYPE(other)->tp_name);
419bool LIST_APPEND1(PyObject *target, PyObject *item) {
420 CHECK_OBJECT(target);
421 assert(PyList_CheckExact(target));
425#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
426 int res = PyList_Append(target, item);
430 PyListObject *list = (PyListObject *)target;
432 Py_ssize_t cur_size = PyList_GET_SIZE(list);
435 assert(cur_size <= PY_SSIZE_T_MAX);
437 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
441 PyList_SET_ITEM(list, cur_size, item);
447bool LIST_APPEND0(PyObject *target, PyObject *item) {
448 CHECK_OBJECT(target);
449 assert(PyList_CheckExact(target));
453#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
454 int res = PyList_Append(target, item);
457 PyListObject *list = (PyListObject *)target;
459 Py_ssize_t cur_size = PyList_GET_SIZE(list);
462 assert(cur_size <= PY_SSIZE_T_MAX);
464 if (LIST_RESIZE(list, cur_size + 1) ==
false) {
468 PyList_SET_ITEM0(list, cur_size, item);
474bool LIST_REMOVE(PyObject *target, PyObject *item) {
475 CHECK_OBJECT(target);
476 assert(PyList_CheckExact(target));
480#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT && 0
482 int res = PyList_Remove(target, item);
485 PyListObject *list = (PyListObject *)target;
487 Py_ssize_t cur_size = PyList_GET_SIZE(list);
489 for (Py_ssize_t i = 0; i < cur_size; i++) {
490 PyObject *element = list->ob_item[i];
493 nuitka_bool cmp = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
496 if (cmp == NUITKA_BOOL_TRUE) {
498 Py_SET_SIZE(list, cur_size - 1);
500 memmove(list->ob_item + i, list->ob_item + i + 1,
sizeof(PyObject *) * (cur_size - i - 1));
503 }
else if (unlikely(cmp == NUITKA_BOOL_EXCEPTION)) {
508 PyThreadState *tstate = PyThreadState_GET();
510 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError,
"list.remove(x): x not in list");
515void LIST_CLEAR(PyObject *target) {
516 CHECK_OBJECT(target);
517 assert(PyList_CheckExact(target));
519 PyListObject *list = (PyListObject *)target;
521 PyObject **items = list->ob_item;
525 Py_ssize_t i = Py_SIZE(list);
526 Py_SET_SIZE(list, 0);
527 list->ob_item = NULL;
531 Py_XDECREF(items[i]);
538PyObject *getListIndexObject(Py_ssize_t value) {
539#if PYTHON_VERSION < 0x300
540 return PyInt_FromSsize_t(value);
544 return Nuitka_LongFromCLong((
long)value);
548PyObject *LIST_COUNT(PyObject *list, PyObject *item) {
550 assert(PyList_CheckExact(list));
552 Py_ssize_t count = 0;
554 for (Py_ssize_t i = 0; i < Py_SIZE(list); i++) {
555 PyObject *element = PyList_GET_ITEM(list, i);
558 if (element == item) {
567 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
570 if (nbool_res == NUITKA_BOOL_TRUE) {
576 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
581 return getListIndexObject(count);
584static PyObject *_LIST_INDEX_COMMON(PyThreadState *tstate, PyListObject *list, PyObject *item, Py_ssize_t start,
588 start += Py_SIZE(list);
596 stop += Py_SIZE(list);
603 for (Py_ssize_t i = start; i < stop && i < Py_SIZE(list); i++) {
604 PyObject *element = list->ob_item[i];
607 nuitka_bool nbool_res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(element, item);
610 if (nbool_res == NUITKA_BOOL_TRUE) {
611 return getListIndexObject(i);
615 if (unlikely(nbool_res == NUITKA_BOOL_EXCEPTION)) {
620#if PYTHON_VERSION < 0x300
621 PyObject *err_format = PyString_FromString(
"%r is not in list");
622 PyObject *format_tuple = MAKE_TUPLE1_0(tstate, item);
623 PyObject *err_string = PyString_Format(err_format, format_tuple);
624 Py_DECREF(format_tuple);
626 if (err_string == NULL) {
630 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_ValueError, err_string);
633 PyErr_Format(PyExc_ValueError,
"%R is not in list", item);
638PyObject *LIST_INDEX2(PyThreadState *tstate, PyObject *list, PyObject *item) {
640 assert(PyList_CheckExact(list));
642 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, 0, Py_SIZE(list));
645PyObject *LIST_INDEX3(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start) {
647 assert(PyList_CheckExact(list));
649 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
651 if (unlikely(start_index == NULL)) {
653 CLEAR_ERROR_OCCURRED(tstate);
655 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
656 "slice indices must be integers or have an __index__ method");
660 Py_ssize_t start_ssize;
661#if PYTHON_VERSION < 0x300
662 if (PyInt_CheckExact(start_index)) {
663 start_ssize = PyInt_AS_LONG(start_index);
665 start_ssize = PyLong_AsSsize_t(start_index);
668 start_ssize = PyLong_AsSsize_t(start_index);
671 Py_DECREF(start_index);
673 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, Py_SIZE(list));
676PyObject *LIST_INDEX4(PyThreadState *tstate, PyObject *list, PyObject *item, PyObject *start, PyObject *stop) {
678 assert(PyList_CheckExact(list));
680 PyObject *start_index = Nuitka_Number_IndexAsLong(start);
682 if (unlikely(start_index == NULL)) {
683 CLEAR_ERROR_OCCURRED(tstate);
685 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
686 "slice indices must be integers or have an __index__ method");
690 Py_ssize_t start_ssize;
691#if PYTHON_VERSION < 0x300
692 if (PyInt_CheckExact(start_index)) {
693 start_ssize = PyInt_AS_LONG(start_index);
695 start_ssize = PyLong_AsSsize_t(start_index);
698 start_ssize = PyLong_AsSsize_t(start_index);
701 Py_DECREF(start_index);
703 PyObject *stop_index = Nuitka_Number_IndexAsLong(stop);
705 if (unlikely(stop_index == NULL)) {
706 Py_DECREF(start_index);
708 CLEAR_ERROR_OCCURRED(tstate);
710 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
711 "slice indices must be integers or have an __index__ method");
715 Py_ssize_t stop_ssize;
716#if PYTHON_VERSION < 0x300
717 if (PyInt_CheckExact(stop_index)) {
718 stop_ssize = PyInt_AS_LONG(stop_index);
720 stop_ssize = PyLong_AsSsize_t(stop_index);
723 stop_ssize = PyLong_AsSsize_t(stop_index);
726 Py_DECREF(stop_index);
728 return _LIST_INDEX_COMMON(tstate, (PyListObject *)list, item, start_ssize, stop_ssize);
731bool LIST_INSERT(PyThreadState *tstate, PyObject *list, PyObject *index, PyObject *item) {
733 assert(PyList_CheckExact(list));
739 PyObject *index_long = Nuitka_Number_IndexAsLong(index);
741 if (unlikely(index_long == NULL)) {
742 CLEAR_ERROR_OCCURRED(tstate);
744 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT(
"'%s' cannot be interpreted as an integer", index);
748 Py_ssize_t index_ssize;
749#if PYTHON_VERSION < 0x300
750 if (PyInt_CheckExact(index_long)) {
751 index_ssize = PyInt_AS_LONG(index_long);
753 index_ssize = PyLong_AsSsize_t(index_long);
756 index_ssize = PyLong_AsSsize_t(index_long);
759 Py_DECREF(index_long);
761 LIST_INSERT_CONST(list, index_ssize, item);
765void LIST_INSERT_CONST(PyObject *list, Py_ssize_t index, PyObject *item) {
767 assert(PyList_CheckExact(list));
770 PyListObject *list_object = (PyListObject *)list;
772 Py_ssize_t n = Py_SIZE(list_object);
775 if (LIST_RESIZE(list_object, n + 1) ==
false) {
791 PyObject **items = list_object->ob_item;
793 for (Py_ssize_t i = n; --i >= index;) {
794 items[i + 1] = items[i];
801static void _Nuitka_ReverseObjectsSlice(PyObject **lo, PyObject **hi) {
802 assert(lo != NULL && hi != NULL);
818void LIST_REVERSE(PyObject *list) {
820 assert(PyList_CheckExact(list));
822 PyListObject *list_object = (PyListObject *)list;
824 if (Py_SIZE(list_object) > 1) {
825 _Nuitka_ReverseObjectsSlice(list_object->ob_item, list_object->ob_item + Py_SIZE(list_object));
829#if PYTHON_VERSION >= 0x300 && !defined(_NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT)
830static bool allocateListItems(PyListObject *list, Py_ssize_t size) {
831 PyObject **items = PyMem_New(PyObject *, size);
833 if (unlikely(items == NULL)) {
838 list->ob_item = items;
839 list->allocated = size;
846PyObject *MAKE_LIST(PyThreadState *tstate, PyObject *iterable) {
849 PyObject *list = MAKE_LIST_EMPTY(tstate, 0);
851#if _NUITKA_EXPERIMENTAL_DISABLE_LIST_OPT
852 PyObject *result = _PyList_Extend((PyListObject *)list, iterable);
853 if (result == NULL) {
863#if PYTHON_VERSION >= 0x300
864 if (Nuitka_PyObject_HasLen(iterable)) {
865 Py_ssize_t iter_len = Nuitka_PyObject_Size(iterable);
867 if (unlikely(iter_len == -1)) {
868 if (!PyErr_ExceptionMatches(PyExc_TypeError)) {
872 CLEAR_ERROR_OCCURRED(tstate);
876 if (allocateListItems((PyListObject *)list, iter_len) ==
false) {
883 bool res = LIST_EXTEND_FROM_ITERABLE(tstate, list, iterable);
887 if (unlikely(res ==
false)) {
896#include "HelpersListsGenerated.c"