10#include "nuitka/prelude.h"
18#define IS_DICT_SHARED(mp) _PyObject_GC_IS_SHARED(mp)
19#define SET_DICT_SHARED(mp) _PyObject_GC_SET_SHARED(mp)
20#define LOAD_INDEX(keys, size, idx) \
21 _Py_atomic_load_int##size##_relaxed(&((const int##size##_t *)keys->dk_indices)[idx]);
22#define STORE_INDEX(keys, size, idx, value) \
23 _Py_atomic_store_int##size##_relaxed(&((int##size##_t *)keys->dk_indices)[idx], (int##size##_t)value);
25#define LOCK_KEYS(keys) PyMutex_LockFlags(&keys->dk_mutex, _Py_LOCK_DONT_DETACH)
26#define UNLOCK_KEYS(keys) PyMutex_Unlock(&keys->dk_mutex)
28#define INCREF_KEYS_FT(dk) Nuitka_Py_dictkeys_incref(dk)
29#define DECREF_KEYS_FT(dk, shared) Nuitka_Py_dictkeys_decref(_PyInterpreterState_GET(), dk, shared)
31#define LOCK_KEYS_IF_SPLIT(keys, kind) \
32 if (kind == DICT_KEYS_SPLIT) { \
36#define UNLOCK_KEYS_IF_SPLIT(keys, kind) \
37 if (kind == DICT_KEYS_SPLIT) { \
43#define LOAD_INDEX(keys, size, idx) ((const int##size##_t *)(keys->dk_indices))[idx]
44#define STORE_INDEX(keys, size, idx, value) ((int##size##_t *)(keys->dk_indices))[idx] = (int##size##_t)value
46#define LOCK_KEYS(keys)
47#define UNLOCK_KEYS(keys)
48#define INCREF_KEYS_FT(dk)
49#define DECREF_KEYS_FT(dk, shared)
50#define LOCK_KEYS_IF_SPLIT(keys, kind)
51#define UNLOCK_KEYS_IF_SPLIT(keys, kind)
55PyObject *DICT_GET_ITEM0(PyThreadState *tstate, PyObject *dict, PyObject *key) {
57 assert(PyDict_Check(dict));
64#if PYTHON_VERSION < 0x300
65 if (PyString_CheckExact(key)) {
66 hash = ((PyStringObject *)key)->ob_shash;
68 if (unlikely(hash == -1)) {
69 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
72 if (unlikely(hash == -1)) {
76 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
78 if (unlikely(hash == -1)) {
83 PyDictObject *dict_object = (PyDictObject *)dict;
84 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
86 if (unlikely(entry == NULL || entry->me_value == NULL)) {
90 CHECK_OBJECT(entry->me_value);
91 return entry->me_value;
93 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
94 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
96 if (unlikely(hash == -1)) {
101 PyDictObject *dict_object = (PyDictObject *)dict;
103#if PYTHON_VERSION < 0x360
104 PyObject **value_addr;
105 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
107 if (unlikely(entry == NULL || *value_addr == NULL)) {
111#if PYTHON_VERSION < 0x370
112 PyObject **value_addr;
113 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
114#elif PYTHON_VERSION < 0x3b0
116 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
118 PyObject **value_addr;
119 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
122 if (unlikely(ix < 0)) {
127#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
128 assert(value_addr != NULL);
129 PyObject *result = *value_addr;
131 if (unlikely(result == NULL)) {
135 CHECK_OBJECT(result);
140PyObject *DICT_GET_ITEM1(PyThreadState *tstate, PyObject *dict, PyObject *key) {
142 assert(PyDict_Check(dict));
149#if PYTHON_VERSION < 0x300
150 if (PyString_CheckExact(key)) {
151 hash = ((PyStringObject *)key)->ob_shash;
153 if (unlikely(hash == -1)) {
154 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
157 if (unlikely(hash == -1)) {
161 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
163 if (unlikely(hash == -1)) {
168 PyDictObject *dict_object = (PyDictObject *)dict;
169 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
171 if (unlikely(entry == NULL || entry->me_value == NULL)) {
175 CHECK_OBJECT(entry->me_value);
176 Py_INCREF(entry->me_value);
177 return entry->me_value;
179 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
180 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
182 if (unlikely(hash == -1)) {
187 PyDictObject *dict_object = (PyDictObject *)dict;
189#if PYTHON_VERSION < 0x360
190 PyObject **value_addr;
191 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
193 if (unlikely(entry == NULL || *value_addr == NULL)) {
197#if PYTHON_VERSION < 0x370
198 PyObject **value_addr;
199 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
200#elif PYTHON_VERSION < 0x3b0
202 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
204 PyObject **value_addr;
205 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
208 if (unlikely(ix < 0)) {
213#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
214 assert(value_addr != NULL);
215 PyObject *result = *value_addr;
217 if (unlikely(result == NULL)) {
221 CHECK_OBJECT(result);
227#if PYTHON_VERSION >= 0x3c0
228static PyObject *Nuitka_CreateKeyError(PyThreadState *tstate, PyObject *key) {
229 return (PyObject *)Nuitka_BaseExceptionSingleArg_new(tstate, (PyTypeObject *)PyExc_KeyError, key);
233static void SET_CURRENT_EXCEPTION_KEY_ERROR(PyThreadState *tstate, PyObject *key) {
234#if PYTHON_VERSION < 0x3c0
239 if (PyTuple_Check(key) || key == Py_None) {
240 PyObject *tuple = MAKE_TUPLE1(tstate, key);
242 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_KeyError, tuple);
244 SET_CURRENT_EXCEPTION_TYPE0_VALUE0(tstate, PyExc_KeyError, key);
249 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
260PyObject *DICT_GET_ITEM_WITH_ERROR(PyThreadState *tstate, PyObject *dict, PyObject *key) {
262 assert(PyDict_CheckExact(dict));
269#if PYTHON_VERSION < 0x300
270 if (PyString_CheckExact(key)) {
271 hash = ((PyStringObject *)key)->ob_shash;
273 if (unlikely(hash == -1)) {
274 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
277 if (unlikely(hash == -1)) {
281 hash = HASH_VALUE_WITH_ERROR(tstate, key);
283 if (unlikely(hash == -1)) {
288 PyDictObject *dict_object = (PyDictObject *)dict;
289 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
291 if (unlikely(entry == NULL || entry->me_value == NULL)) {
292 SET_CURRENT_EXCEPTION_KEY_ERROR(tstate, key);
297 CHECK_OBJECT(entry->me_value);
298 Py_INCREF(entry->me_value);
299 return entry->me_value;
301 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
302 hash = HASH_VALUE_WITH_ERROR(tstate, key);
303 if (unlikely(hash == -1)) {
308 PyDictObject *dict_object = (PyDictObject *)dict;
310#if PYTHON_VERSION < 0x360
311 PyObject **value_addr;
312 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
314 if (unlikely(entry == NULL || *value_addr == NULL)) {
315 if (unlikely(HAS_ERROR_OCCURRED(tstate))) {
319 SET_CURRENT_EXCEPTION_KEY_ERROR(tstate, key);
324#if PYTHON_VERSION < 0x370
325 PyObject **value_addr;
326 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
327#elif PYTHON_VERSION < 0x3b0
329 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
331 PyObject **value_addr;
332 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
335 if (unlikely(ix < 0)) {
336 if (unlikely(HAS_ERROR_OCCURRED(tstate))) {
340 SET_CURRENT_EXCEPTION_KEY_ERROR(tstate, key);
346#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
347 assert(value_addr != NULL);
348 PyObject *result = *value_addr;
351 if (unlikely(result == NULL)) {
352 if (unlikely(HAS_ERROR_OCCURRED(tstate))) {
356 SET_CURRENT_EXCEPTION_KEY_ERROR(tstate, key);
361 CHECK_OBJECT(result);
367PyObject *DICT_GET_ITEM_WITH_HASH_ERROR0(PyThreadState *tstate, PyObject *dict, PyObject *key) {
369 assert(PyDict_CheckExact(dict));
376#if PYTHON_VERSION < 0x300
377 if (PyString_CheckExact(key)) {
378 hash = ((PyStringObject *)key)->ob_shash;
380 if (unlikely(hash == -1)) {
381 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
384 if (unlikely(hash == -1)) {
388 hash = HASH_VALUE_WITH_ERROR(tstate, key);
390 if (unlikely(hash == -1)) {
395 PyDictObject *dict_object = (PyDictObject *)dict;
396 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
398 if (unlikely(entry == NULL || entry->me_value == NULL)) {
402 CHECK_OBJECT(entry->me_value);
403 return entry->me_value;
405 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
406 hash = HASH_VALUE_WITH_ERROR(tstate, key);
407 if (unlikely(hash == -1)) {
412 PyDictObject *dict_object = (PyDictObject *)dict;
414#if PYTHON_VERSION < 0x360
415 PyObject **value_addr;
416 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
418 if (unlikely(entry == NULL || *value_addr == NULL)) {
422#if PYTHON_VERSION < 0x370
423 PyObject **value_addr;
424 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
425#elif PYTHON_VERSION < 0x3b0
427 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
429 PyObject **value_addr;
430 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
433 if (unlikely(ix < 0)) {
438#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
439 assert(value_addr != NULL);
440 PyObject *result = *value_addr;
443 if (unlikely(result == NULL)) {
447 CHECK_OBJECT(result);
455PyObject *DICT_GET_ITEM_WITH_HASH_ERROR1(PyThreadState *tstate, PyObject *dict, PyObject *key) {
457 assert(PyDict_CheckExact(dict));
464#if PYTHON_VERSION < 0x300
465 if (PyString_CheckExact(key)) {
466 hash = ((PyStringObject *)key)->ob_shash;
468 if (unlikely(hash == -1)) {
469 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
472 if (unlikely(hash == -1)) {
476 hash = HASH_VALUE_WITH_ERROR(tstate, key);
478 if (unlikely(hash == -1)) {
483 PyDictObject *dict_object = (PyDictObject *)dict;
484 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
486 if (unlikely(entry == NULL || entry->me_value == NULL)) {
490 CHECK_OBJECT(entry->me_value);
491 Py_INCREF(entry->me_value);
492 return entry->me_value;
494 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
495 hash = HASH_VALUE_WITH_ERROR(tstate, key);
496 if (unlikely(hash == -1)) {
501 PyDictObject *dict_object = (PyDictObject *)dict;
503#if PYTHON_VERSION < 0x360
504 PyObject **value_addr;
505 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
507 if (unlikely(entry == NULL || *value_addr == NULL)) {
511#if PYTHON_VERSION < 0x370
512 PyObject **value_addr;
513 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
514#elif PYTHON_VERSION < 0x3b0
516 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
518 PyObject **value_addr;
519 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
522 if (unlikely(ix < 0)) {
527#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
528 assert(value_addr != NULL);
529 PyObject *result = *value_addr;
532 if (unlikely(result == NULL)) {
536 CHECK_OBJECT(result);
542int DICT_HAS_ITEM(PyThreadState *tstate, PyObject *dict, PyObject *key) {
544 assert(PyDict_Check(dict));
551#if PYTHON_VERSION < 0x300
552 if (PyString_CheckExact(key)) {
553 hash = ((PyStringObject *)key)->ob_shash;
555 if (unlikely(hash == -1)) {
556 hash = HASH_VALUE_WITHOUT_ERROR(tstate, key);
559 if (unlikely(hash == -1)) {
563 hash = HASH_VALUE_WITH_ERROR(tstate, key);
565 if (unlikely(hash == -1)) {
570 PyDictObject *dict_object = (PyDictObject *)dict;
571 PyDictEntry *entry = (dict_object->ma_lookup)(dict_object, key, hash);
573 if (unlikely(entry == NULL || entry->me_value == NULL)) {
579 if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *)key)->hash) == -1) {
580 hash = HASH_VALUE_WITH_ERROR(tstate, key);
581 if (unlikely(hash == -1)) {
586 PyDictObject *dict_object = (PyDictObject *)dict;
588#if PYTHON_VERSION < 0x360
589 PyObject **value_addr;
590 PyDictKeyEntry *entry = dict_object->ma_keys->dk_lookup(dict_object, key, hash, &value_addr);
592 if (unlikely(entry == NULL || *value_addr == NULL)) {
598#if PYTHON_VERSION < 0x370
599 PyObject **value_addr;
600 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &value_addr, NULL);
601#elif PYTHON_VERSION < 0x3b0
603 Py_ssize_t ix = (dict_object->ma_keys->dk_lookup)(dict_object, key, hash, &result);
605 PyObject **value_addr;
606 Py_ssize_t ix = Nuitka_PyDictLookup(dict_object, key, hash, &value_addr);
609 if (unlikely(ix < 0)) {
610 if (unlikely(HAS_ERROR_OCCURRED(tstate))) {
617#if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
618 assert(value_addr != NULL);
619 PyObject *result = *value_addr;
622 if (unlikely(result == NULL)) {
630#if PYTHON_VERSION < 0x300
631PyObject *DICT_ITEMS(PyObject *dict) {
633 assert(PyDict_Check(dict));
635 PyDictObject *mp = (PyDictObject *)dict;
646 result = MAKE_LIST_EMPTY(tstate, size);
647 CHECK_OBJECT(result);
649 for (Py_ssize_t i = 0; i < size; i++) {
651 PyObject *item = MAKE_TUPLE_EMPTY(tstate, 2);
654 PyList_SET_ITEM(result, i, item);
657 if (unlikely(size != mp->ma_used)) {
664 PyDictEntry *ep = mp->ma_table;
665 Py_ssize_t mask = mp->ma_mask;
667 for (Py_ssize_t i = 0, j = 0; i <= mask; i++) {
668 PyObject *value = ep[i].me_value;
670 PyObject *key = ep[i].me_key;
671 PyObject *item = PyList_GET_ITEM(result, j);
672 PyTuple_SET_ITEM0(item, 0, key);
673 PyTuple_SET_ITEM0(item, 1, value);
679 assert(PyList_GET_SIZE(result) == size);
684#if PYTHON_VERSION < 0x300
685PyObject *DICT_KEYS(PyObject *dict) {
687 assert(PyDict_Check(dict));
689 PyDictObject *mp = (PyDictObject *)dict;
700 result = MAKE_LIST_EMPTY(tstate, size);
701 CHECK_OBJECT(result);
703 if (unlikely(size != mp->ma_used)) {
710 PyDictEntry *ep = mp->ma_table;
711 Py_ssize_t mask = mp->ma_mask;
713 for (Py_ssize_t i = 0, j = 0; i <= mask; i++) {
714 PyObject *value = ep[i].me_value;
716 PyObject *key = ep[i].me_key;
717 PyList_SET_ITEM0(result, j, key);
723 assert(PyList_GET_SIZE(result) == size);
729#if PYTHON_VERSION < 0x300
730PyObject *DICT_VALUES(PyObject *dict) {
732 assert(PyDict_Check(dict));
734 PyDictObject *mp = (PyDictObject *)dict;
745 result = MAKE_LIST_EMPTY(tstate, size);
746 CHECK_OBJECT(result);
748 if (unlikely(size != mp->ma_used)) {
755 PyDictEntry *ep = mp->ma_table;
756 Py_ssize_t mask = mp->ma_mask;
758 for (Py_ssize_t i = 0, j = 0; i <= mask; i++) {
759 PyObject *value = ep[i].me_value;
761 PyList_SET_ITEM0(result, j, value);
767 assert(PyList_GET_SIZE(result) == size);
775#if PYTHON_VERSION < 0x300
777 PyObject_HEAD PyDictObject *di_dict;
785#if PYTHON_VERSION >= 0x300 && PYTHON_VERSION < 0x350
787 PyObject_HEAD PyDictObject *dv_dict;
793static inline PyObject *_MAKE_DICT_ITERATOR(PyThreadState *tstate, PyDictObject *dict, PyTypeObject *type,
795 CHECK_OBJECT((PyObject *)dict);
796 assert(PyDict_CheckExact((PyObject *)dict));
798#if PYTHON_VERSION < 0x300
803 di->di_used = dict->ma_used;
805 di->len = dict->ma_used;
808 di->di_result = MAKE_TUPLE2(tstate, Py_None, Py_None);
809 CHECK_OBJECT(di->di_result);
811 di->di_result = NULL;
815 return (PyObject *)di;
817 _PyDictViewObject *dv = (_PyDictViewObject *)Nuitka_GC_New(type);
824 return (PyObject *)dv;
828PyObject *DICT_ITERITEMS(PyThreadState *tstate, PyObject *dict) {
829#if PYTHON_VERSION < 0x270
830 static PyTypeObject *dictiteritems_type = NULL;
832 if (unlikely(dictiteritems_type == NULL)) {
834 Py_TYPE(CALL_FUNCTION_NO_ARGS(tstate, PyObject_GetAttrString(const_dict_empty,
"iteritems")));
837 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, dictiteritems_type,
true);
838#elif PYTHON_VERSION < 0x300
839 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictIterItem_Type,
true);
841 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictItems_Type,
true);
845PyObject *DICT_ITERKEYS(PyThreadState *tstate, PyObject *dict) {
846#if PYTHON_VERSION < 0x270
847 static PyTypeObject *dictiterkeys_type = NULL;
849 if (unlikely(dictiterkeys_type == NULL)) {
851 Py_TYPE(CALL_FUNCTION_NO_ARGS(tstate, PyObject_GetAttrString(const_dict_empty,
"iterkeys")));
854 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, dictiterkeys_type,
false);
855#elif PYTHON_VERSION < 0x300
856 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictIterKey_Type,
false);
858 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictKeys_Type,
false);
862PyObject *DICT_ITERVALUES(PyThreadState *tstate, PyObject *dict) {
863#if PYTHON_VERSION < 0x270
864 static PyTypeObject *dictitervalues_type = NULL;
866 if (unlikely(dictitervalues_type == NULL)) {
867 dictitervalues_type =
868 Py_TYPE(CALL_FUNCTION_NO_ARGS(tstate, PyObject_GetAttrString(const_dict_empty,
"itervalues")));
871 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, dictitervalues_type,
false);
872#elif PYTHON_VERSION < 0x300
873 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictIterValue_Type,
false);
875 return _MAKE_DICT_ITERATOR(tstate, (PyDictObject *)dict, &PyDictValues_Type,
false);
880 PyObject_HEAD PyDictObject *dv_dict;
883static PyObject *_MAKE_DICT_VIEW(PyDictObject *dict, PyTypeObject *type) {
884 CHECK_OBJECT((PyObject *)dict);
885 assert(PyDict_CheckExact((PyObject *)dict));
891 dv->dv_dict = (PyDictObject *)dict;
893 return (PyObject *)dv;
896PyObject *DICT_VIEWKEYS(PyObject *dict) {
897#if PYTHON_VERSION < 0x270
898 static PyTypeObject *dictkeysview_type = NULL;
900 if (unlikely(dictkeysview_type)) {
901 dictkeysview_type = Py_TYPE(PyObject_GetIter(PyObject_GetAttrString(const_dict_empty,
"viewkeys")));
904 return _MAKE_DICT_VIEW((PyDictObject *)dict, dictkeysview_type);
906 return _MAKE_DICT_VIEW((PyDictObject *)dict, &PyDictKeys_Type);
910PyObject *DICT_VIEWVALUES(PyObject *dict) {
911#if PYTHON_VERSION < 0x270
912 static PyTypeObject *dictvaluesview_type = NULL;
914 if (unlikely(dictvaluesview_type)) {
915 dictvaluesview_type = Py_TYPE(PyObject_GetIter(PyObject_GetAttrString(const_dict_empty,
"viewvalues")));
918 return _MAKE_DICT_VIEW((PyDictObject *)dict, dictvaluesview_type);
920 return _MAKE_DICT_VIEW((PyDictObject *)dict, &PyDictValues_Type);
924PyObject *DICT_VIEWITEMS(PyObject *dict) {
925#if PYTHON_VERSION < 0x270
926 static PyTypeObject *dictvaluesview_type = NULL;
928 if (unlikely(dictvaluesview_type)) {
929 dictvaluesview_type = Py_TYPE(PyObject_GetIter(PyObject_GetAttrString(const_dict_empty,
"viewitems")));
932 return _MAKE_DICT_VIEW((PyDictObject *)dict, dictvaluesview_type);
934 return _MAKE_DICT_VIEW((PyDictObject *)dict, &PyDictItems_Type);
938#if PYTHON_VERSION >= 0x300
939static PyDictObject *_Nuitka_AllocatePyDictObject(PyThreadState *tstate) {
940 PyDictObject *result_mp;
942#if NUITKA_DICT_HAS_FREELIST
945#if PYTHON_VERSION < 0x3d0
946 PyDictObject **items = tstate->interp->dict_state.free_list;
947 int *numfree = &tstate->interp->dict_state.numfree;
949 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
950 struct _Py_dict_freelist *state = &freelists->dicts;
951 PyDictObject **items = state->items;
952 int *numfree = &state->numfree;
957 result_mp = items[*numfree];
959 Nuitka_Py_NewReference((PyObject *)result_mp);
961 assert(PyDict_CheckExact((PyObject *)result_mp));
962 assert(result_mp != NULL);
966 result_mp = (PyDictObject *)Nuitka_GC_New(&PyDict_Type);
973#if PYTHON_VERSION >= 0x360
974static PyDictKeysObject *_Nuitka_AllocatePyDictKeysObject(PyThreadState *tstate, Py_ssize_t keys_size) {
976 PyDictKeysObject *dk;
981#if NUITKA_DICT_HAS_FREELIST && 0
982#if PYTHON_VERSION < 0x3d0
983 PyDictKeysObject **items = tstate->interp->dict_state.keys_free_list;
984 int *numfree = &tstate->interp->dict_state.keys_numfree;
986 struct _Py_object_freelists *freelists = _Nuitka_object_freelists_GET(tstate);
987 struct _Py_dictkeys_freelist *state = &freelists->dictkeys;
988 PyDictKeysObject **items = state->items;
989 int *numfree = &state->numfree;
994 dk = items[*numfree];
998#if PYTHON_VERSION < 0x3d0
999 dk = (PyDictKeysObject *)NuitkaObject_Malloc(keys_size);
1001 dk = (PyDictKeysObject *)NuitkaMem_Malloc(keys_size);
1009#if PYTHON_VERSION >= 0x360 && !defined(_NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT)
1012#define DK_USABLE_FRACTION(n) (((n) << 1) / 3)
1014static Py_ssize_t _Nuitka_Py_PyDict_KeysSize(PyDictKeysObject *keys) {
1015#if PYTHON_VERSION < 0x360
1016 return sizeof(PyDictKeysObject) + (DK_SIZE(keys) - 1) *
sizeof(PyDictKeyEntry);
1017#elif PYTHON_VERSION < 0x370
1018 return (
sizeof(PyDictKeysObject) - Py_MEMBER_SIZE(PyDictKeysObject, dk_indices) + DK_IXSIZE(keys) * DK_SIZE(keys) +
1019 DK_USABLE_FRACTION(DK_SIZE(keys)) *
sizeof(PyDictKeyEntry));
1020#elif PYTHON_VERSION < 0x3b0
1021 return (
sizeof(PyDictKeysObject) + DK_IXSIZE(keys) * DK_SIZE(keys) +
1022 DK_USABLE_FRACTION(DK_SIZE(keys)) *
sizeof(PyDictKeyEntry));
1024 size_t entry_size = keys->dk_kind == DICT_KEYS_GENERAL ?
sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry);
1025 return (
sizeof(PyDictKeysObject) + ((
size_t)1 << keys->dk_log2_index_bytes) +
1026 DK_USABLE_FRACTION(DK_SIZE(keys)) * entry_size);
1031#if PYTHON_VERSION < 0x3b0
1032typedef PyObject *PyDictValues;
1035#if PYTHON_VERSION < 0x360
1036#define DK_ENTRIES_SIZE(keys) (keys->dk_size)
1037#elif PYTHON_VERSION < 0x3b0
1038#define DK_ENTRIES_SIZE(keys) DK_USABLE_FRACTION(DK_SIZE(keys))
1040#define DK_ENTRIES_SIZE(keys) (keys->dk_nentries)
1044#if PYTHON_VERSION < 0x360
1045#define IS_COMPACT(dict_mp) (dict_mp->ma_used >= (dict_mp->ma_keys->dk_size * 2) / 3)
1047#define IS_COMPACT(dict_mp) (dict_mp->ma_used >= (dict_mp->ma_keys->dk_nentries * 2) / 3)
1050static inline PyDictValues *_Nuitka_PyDict_new_values(Py_ssize_t size) {
1051#if PYTHON_VERSION < 0x3b0
1052 Py_ssize_t values_size =
sizeof(PyObject *) * size;
1054 return (PyDictValues *)NuitkaMem_Malloc(values_size);
1055#elif PYTHON_VERSION < 0x3d0
1056 Py_ssize_t values_size =
sizeof(PyObject *) * size;
1059 size_t prefix_size = _Py_SIZE_ROUND_UP(size + 2,
sizeof(PyObject *));
1060 size_t n = prefix_size + values_size;
1061 uint8_t *mem = (uint8_t *)NuitkaMem_Malloc(n);
1062 assert(mem != NULL);
1064 assert(prefix_size %
sizeof(PyObject *) == 0);
1065 mem[prefix_size - 1] = (uint8_t)prefix_size;
1067 return (PyDictValues *)(mem + prefix_size);
1070 size_t suffix_size = _Py_SIZE_ROUND_UP(size,
sizeof(PyObject *));
1071 assert(suffix_size < 128);
1072 assert(suffix_size %
sizeof(PyObject *) == 0);
1073 size_t n = (size + 1) *
sizeof(PyObject *) + suffix_size;
1074 PyDictValues *result = (PyDictValues *)NuitkaMem_Malloc(n);
1076 result->embedded = 0;
1079 result->capacity = (uint8_t)size;
1084#if PYTHON_VERSION >= 0x3d0
1086static PyDictValues *_Nuitka_PyDict_copy_values(PyDictValues *values) {
1087 PyDictValues *new_values = _Nuitka_PyDict_new_values(values->capacity);
1088 if (unlikely(new_values == NULL)) {
1092 new_values->size = values->size;
1094 uint8_t *values_order = get_insertion_order_array(values);
1095 uint8_t *new_values_order = get_insertion_order_array(new_values);
1097 memcpy(new_values_order, values_order, values->capacity);
1099 for (
int i = 0; i < values->capacity; i++) {
1100 new_values->values[i] = values->values[i];
1102 assert(new_values->embedded == 0);
1107#include "HelpersDictionariesGenerated.c"
1109void DICT_CLEAR(PyObject *dict) {
1111 assert(PyDict_CheckExact(dict));
1118#if PYTHON_VERSION >= 0x3b0
1119static inline int Nuitka_py_get_index_from_order(PyDictObject *mp, Py_ssize_t i) {
1120 assert(mp->ma_used <= SHARED_KEYS_MAX_SIZE);
1121#if PYTHON_VERSION < 0x3d0
1122 assert(i < (((
char *)mp->ma_values)[-2]));
1123 return ((
char *)mp->ma_values)[-3 - i];
1125 assert(i < mp->ma_values->size);
1126 uint8_t *array = get_insertion_order_array(mp->ma_values);
1132#if PYTHON_VERSION >= 0x3b0
1134static inline Py_ssize_t Nuitka_Py_dictkeys_get_index(
const PyDictKeysObject *keys, Py_ssize_t i) {
1135 int log2size = DK_LOG_SIZE(keys);
1139 ix = LOAD_INDEX(keys, 8, i);
1141 }
else if (log2size < 16) {
1142 ix = LOAD_INDEX(keys, 16, i);
1144#if SIZEOF_VOID_P > 4
1145 else if (log2size >= 32) {
1146 ix = LOAD_INDEX(keys, 64, i);
1150 ix = LOAD_INDEX(keys, 32, i);
1153 assert(ix >= DKIX_DUMMY);
1158#define PERTURB_SHIFT 5
1160static Py_ssize_t Nuitka_Py_unicodekeys_lookup_generic(PyDictObject *mp, PyDictKeysObject *dk, PyObject *key,
1162 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk);
1164 size_t mask = DK_MASK(dk);
1165 size_t perturb = hash;
1166 size_t i = (size_t)hash & mask;
1169 Py_ssize_t ix = Nuitka_Py_dictkeys_get_index(dk, i);
1172 PyDictUnicodeEntry *ep = &ep0[ix];
1174 assert(ep->me_key != NULL);
1175 assert(PyUnicode_CheckExact(ep->me_key));
1177 if (ep->me_key == key) {
1181 if (Nuitka_Py_unicode_get_hash(ep->me_key) == hash) {
1182 PyObject *startkey = ep->me_key;
1183 Py_INCREF(startkey);
1184 nuitka_bool cmp = RICH_COMPARE_EQ_NBOOL_UNICODE_OBJECT(startkey, key);
1185 Py_DECREF(startkey);
1187 if (unlikely(cmp == NUITKA_BOOL_EXCEPTION)) {
1191 if (dk == mp->ma_keys && ep->me_key == startkey) {
1192 if (cmp == NUITKA_BOOL_TRUE) {
1197 return DKIX_KEY_CHANGED;
1200 }
else if (ix == DKIX_EMPTY) {
1203 perturb >>= PERTURB_SHIFT;
1204 i = mask & (i * 5 + perturb + 1);
1207 NUITKA_CANNOT_GET_HERE(
"Nuitka_Py_unicodekeys_lookup_generic failed");
1210Py_ssize_t Nuitka_Py_unicodekeys_lookup_unicode(PyDictKeysObject *dk, PyObject *key, Py_hash_t hash) {
1211 assert(PyUnicode_CheckExact(key));
1212 assert(dk->dk_kind != DICT_KEYS_GENERAL);
1214 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk);
1216 size_t mask = DK_MASK(dk);
1217 size_t perturb = hash;
1218 size_t i = (size_t)hash & mask;
1221 Py_ssize_t ix = Nuitka_Py_dictkeys_get_index(dk, i);
1225 PyDictUnicodeEntry *ep = &ep0[ix];
1226 assert(ep->me_key != NULL);
1227 assert(PyUnicode_CheckExact(ep->me_key));
1229 if (ep->me_key == key || (Nuitka_Py_unicode_get_hash(ep->me_key) == hash &&
1230 RICH_COMPARE_EQ_CBOOL_UNICODE_UNICODE(ep->me_key, key))) {
1233 }
else if (ix == DKIX_EMPTY) {
1236 perturb >>= PERTURB_SHIFT;
1238 i = mask & (i * 5 + perturb + 1);
1239 ix = Nuitka_Py_dictkeys_get_index(dk, i);
1242 PyDictUnicodeEntry *ep = &ep0[ix];
1244 assert(ep->me_key != NULL);
1245 assert(PyUnicode_CheckExact(ep->me_key));
1247 if (ep->me_key == key || (Nuitka_Py_unicode_get_hash(ep->me_key) == hash &&
1248 RICH_COMPARE_EQ_CBOOL_UNICODE_UNICODE(ep->me_key, key))) {
1251 }
else if (ix == DKIX_EMPTY) {
1255 perturb >>= PERTURB_SHIFT;
1256 i = mask & (i * 5 + perturb + 1);
1259 NUITKA_CANNOT_GET_HERE(
"Nuitka_Py_unicodekeys_lookup_unicode failed");
1263static Py_ssize_t Nuitka_Py_dictkeys_generic_lookup(PyDictObject *mp, PyDictKeysObject *dk, PyObject *key,
1265 PyDictKeyEntry *ep0 = DK_ENTRIES(dk);
1267 size_t mask = DK_MASK(dk);
1268 size_t perturb = hash;
1269 size_t i = (size_t)hash & mask;
1272 Py_ssize_t ix = Nuitka_Py_dictkeys_get_index(dk, i);
1275 PyDictKeyEntry *ep = &ep0[ix];
1276 assert(ep->me_key != NULL);
1277 if (ep->me_key == key) {
1280 if (ep->me_hash == hash) {
1281 PyObject *startkey = ep->me_key;
1282 Py_INCREF(startkey);
1283 nuitka_bool cmp = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(startkey, key);
1284 Py_DECREF(startkey);
1286 if (unlikely(cmp == NUITKA_BOOL_EXCEPTION)) {
1289 if (dk == mp->ma_keys && ep->me_key == startkey) {
1290 if (cmp == NUITKA_BOOL_TRUE) {
1295 return DKIX_KEY_CHANGED;
1298 }
else if (ix == DKIX_EMPTY) {
1301 perturb >>= PERTURB_SHIFT;
1302 i = mask & (i * 5 + perturb + 1);
1306Py_ssize_t Nuitka_PyDictLookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr) {
1307 PyDictKeysObject *dk;
1311 _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(mp);
1314 kind = (DictKeysKind)dk->dk_kind;
1316 if (kind != DICT_KEYS_GENERAL) {
1317 if (PyUnicode_CheckExact(key)) {
1318#ifdef Py_GIL_DISABLED
1319 if (kind == DICT_KEYS_SPLIT) {
1320 ix = Nuitka_Py_unicodekeys_lookup_unicode_threadsafe(dk, key, hash);
1322 if (ix == DKIX_KEY_CHANGED) {
1324 ix = Nuitka_Py_unicodekeys_lookup_unicode(dk, key, hash);
1330 ix = Nuitka_Py_unicodekeys_lookup_unicode(dk, key, hash);
1334 LOCK_KEYS_IF_SPLIT(dk, kind);
1336 ix = Nuitka_Py_unicodekeys_lookup_generic(mp, dk, key, hash);
1338 UNLOCK_KEYS_IF_SPLIT(dk, kind);
1339 DECREF_KEYS_FT(dk, IS_DICT_SHARED(mp));
1342 if (ix == DKIX_KEY_CHANGED) {
1348 if (kind == DICT_KEYS_SPLIT) {
1349 *value_addr = &mp->ma_values->values[ix];
1351 *value_addr = &DK_UNICODE_ENTRIES(dk)[ix].me_value;
1357 ix = Nuitka_Py_dictkeys_generic_lookup(mp, dk, key, hash);
1360 if (ix == DKIX_KEY_CHANGED) {
1365 *value_addr = &DK_ENTRIES(dk)[ix].me_value;
1374Py_ssize_t Nuitka_PyDictLookupStr(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr) {
1375 assert(PyUnicode_CheckExact(key));
1377 PyDictKeysObject *dk = mp->ma_keys;
1378 assert(dk->dk_kind != DICT_KEYS_GENERAL);
1380 Py_ssize_t ix = Nuitka_Py_unicodekeys_lookup_unicode(dk, key, hash);
1383 if (dk->dk_kind == DICT_KEYS_SPLIT) {
1384 *value_addr = &mp->ma_values->values[ix];
1386 *value_addr = &DK_UNICODE_ENTRIES(dk)[ix].me_value;
1397bool Nuitka_DictNext(PyObject *dict, Py_ssize_t *pos, PyObject **key_ptr, PyObject **value_ptr) {
1399 assert(PyDict_CheckExact(dict));
1400 assert(key_ptr != NULL);
1401 assert(value_ptr != NULL);
1403#if PYTHON_VERSION < 0x300
1404 Py_ssize_t i = *pos;
1406 PyDictEntry *ep = ((PyDictObject *)dict)->ma_table;
1407 Py_ssize_t mask = ((PyDictObject *)dict)->ma_mask;
1409 while (i <= mask && ep[i].me_value == NULL) {
1419 *key_ptr = ep[i].me_key;
1420 *value_ptr = ep[i].me_value;
1424#elif PYTHON_VERSION < 0x360
1425 PyDictObject *mp = (PyDictObject *)dict;
1426 PyObject **dict_value_ptr;
1429 Py_ssize_t i = *pos;
1432 if (mp->ma_values) {
1433 dict_value_ptr = &mp->ma_values[i];
1434 offset =
sizeof(PyObject *);
1436 dict_value_ptr = &mp->ma_keys->dk_entries[i].me_value;
1437 offset =
sizeof(PyDictKeyEntry);
1440 Py_ssize_t mask = DK_MASK(mp->ma_keys);
1442 while ((i <= mask) && (*dict_value_ptr == NULL)) {
1443 dict_value_ptr = (PyObject **)(((
char *)dict_value_ptr) + offset);
1451 *key_ptr = mp->ma_keys->dk_entries[i].me_key;
1452 *value_ptr = *dict_value_ptr;
1457#elif PYTHON_VERSION < 0x3b0
1458 PyDictObject *mp = (PyDictObject *)dict;
1459 PyDictKeyEntry *entry;
1462 Py_ssize_t i = *pos;
1465 if (mp->ma_values) {
1466 if (i >= mp->ma_used) {
1470 entry = &DK_ENTRIES(mp->ma_keys)[i];
1471 value = DK_VALUE(mp, i);
1473 assert(value != NULL);
1475 Py_ssize_t n = mp->ma_keys->dk_nentries;
1481 entry = &DK_ENTRIES(mp->ma_keys)[i];
1483 while (i < n && entry->me_value == NULL) {
1492 value = entry->me_value;
1497 *key_ptr = entry->me_key;
1502 PyDictObject *mp = (PyDictObject *)dict;
1503 Py_ssize_t i = *pos;
1504 PyObject *key, *value;
1506 if (mp->ma_values) {
1508 assert(mp->ma_used <= SHARED_KEYS_MAX_SIZE);
1510 if (i >= mp->ma_used) {
1514 int index = Nuitka_py_get_index_from_order(mp, i);
1515 value = mp->ma_values->values[index];
1517 key = DK_UNICODE_ENTRIES(mp->ma_keys)[index].me_key;
1519 assert(value != NULL);
1521 Py_ssize_t n = mp->ma_keys->dk_nentries;
1529 if (DK_IS_UNICODE(mp->ma_keys)) {
1530 PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(mp->ma_keys)[i];
1532 while (i < n && entry_ptr->me_value == NULL) {
1541 key = entry_ptr->me_key;
1542 value = entry_ptr->me_value;
1544 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1546 while (i < n && entry_ptr->me_value == NULL) {
1555 key = entry_ptr->me_key;
1556 value = entry_ptr->me_value;
1569PyObject *TO_DICT(PyThreadState *tstate, PyObject *seq_obj, PyObject *dict_obj) {
1572 if (seq_obj != NULL) {
1573 CHECK_OBJECT(seq_obj);
1576 if (PyDict_CheckExact(seq_obj)) {
1577 result = DICT_COPY(tstate, seq_obj);
1579 result = MAKE_DICT_EMPTY(tstate);
1583#if PYTHON_VERSION >= 0x300
1584 int res = HAS_ATTR_BOOL2(tstate, seq_obj, const_str_plain_keys);
1586 if (unlikely(res == -1)) {
1591 int res = HAS_ATTR_BOOL(tstate, seq_obj, const_str_plain_keys) ? 1 : 0;
1595 res = PyDict_Merge(result, seq_obj, 1);
1597 res = PyDict_MergeFromSeq2(result, seq_obj, 1);
1602 if (unlikely(res == -1)) {
1607 result = MAKE_DICT_EMPTY(tstate);
1612 if (dict_obj != NULL) {
1613 CHECK_OBJECT(dict_obj);
1615 int res = PyDict_Merge(result, dict_obj, 1);
1617 if (unlikely(res == -1)) {
1625#if _NUITKA_MAINTAIN_DICT_VERSION_TAG
1626uint64_t nuitka_dict_version_tag_counter = ((uint64_t)1) << 32;
1629#if NUITKA_DICT_HAS_FREELIST
1630PyObject *MAKE_DICT_EMPTY(PyThreadState *tstate) {
1631 PyDictObject *empty_dict_mp = (PyDictObject *)const_dict_empty;
1633#if PYTHON_VERSION < 0x3c0
1634 empty_dict_mp->ma_keys->dk_refcnt++;
1637 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
1639 result_mp->ma_keys = empty_dict_mp->ma_keys;
1640 result_mp->ma_values = empty_dict_mp->ma_values;
1641 result_mp->ma_used = 0;
1642#if PYTHON_VERSION >= 0x3c0
1643 result_mp->ma_version_tag = DICT_NEXT_VERSION(_PyInterpreterState_GET());
1644#elif PYTHON_VERSION >= 0x360
1645 result_mp->ma_version_tag = 1;
1649#if defined(Py_REF_DEBUG) && PYTHON_VERSION < 0x3c0
1654 return (PyObject *)result_mp;
1658PyObject *MAKE_DICT(PyObject **pairs, Py_ssize_t size) {
1659 PyObject *result = _PyDict_NewPresized(size);
1663 for (Py_ssize_t i = 0; i < size; i++) {
1664 PyObject *key = pairs[i * 2];
1665 PyObject *value = pairs[i * 2 + 1];
1667 int res = PyDict_SetItem(result, key, value);
1669 if (unlikely(res != 0)) {
1678PyObject *MAKE_DICT_X(PyObject **pairs, Py_ssize_t size) {
1679 PyObject *result = _PyDict_NewPresized(size);
1683 for (Py_ssize_t i = 0; i < size; i++) {
1684 PyObject *value = pairs[i * 2 + 1];
1686 if (value != NULL) {
1687 PyObject *key = pairs[i * 2];
1689 CHECK_OBJECT(value);
1691 int res = PyDict_SetItem(result, key, value);
1693 if (unlikely(res != 0)) {
1703PyObject *MAKE_DICT_X_CSTR(
char const **keys, PyObject **values, Py_ssize_t size) {
1704 PyObject *result = _PyDict_NewPresized(size);
1708 for (Py_ssize_t i = 0; i < size; i++) {
1709 PyObject *value = values[i];
1711 if (value != NULL) {
1712 CHECK_OBJECT(value);
1714 int res = PyDict_SetItemString(result, keys[i], value);
1716 if (unlikely(res != 0)) {
Definition exceptions.h:712
Definition HelpersDictionaries.c:776
Definition HelpersDictionaries.c:879