5#include "nuitka/prelude.h"
10PyObject *DICT_COPY(PyThreadState *tstate, PyObject *dict_value) {
11#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
12 CHECK_OBJECT(dict_value);
13 assert(PyDict_CheckExact(dict_value));
15 return PyDict_Copy(dict_value);
18 Py_BEGIN_CRITICAL_SECTION(dict_value);
20 CHECK_OBJECT(dict_value);
21 assert(PyDict_CheckExact(dict_value));
23 if (((PyDictObject *)dict_value)->ma_used == 0) {
24 result = MAKE_DICT_EMPTY(tstate);
26 PyDictObject *dict_mp = (PyDictObject *)dict_value;
28#if PYTHON_VERSION < 0x300
31 result = _PyDict_NewPresized(dict_mp->ma_used);
33 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
34 PyDictEntry *entry = &dict_mp->ma_table[i];
36 if (entry->me_value != NULL) {
37 PyObject *key = entry->me_key;
39 PyObject *value = entry->me_value;
41 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
47 if (_PyDict_HasSplitTable(dict_mp)) {
48 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
49 assert(result_mp != NULL);
50 result = (PyObject *)result_mp;
52#if PYTHON_VERSION < 0x3b0
53 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
55 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
58#if PYTHON_VERSION < 0x3d0
59 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
60 assert(new_values != NULL);
62#if PYTHON_VERSION >= 0x3b0
64 size_t prefix_size = ((uint8_t *)new_values)[-1];
65 memcpy((
char *)new_values - prefix_size, (
char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
68 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
71 result_mp->ma_values = new_values;
72 result_mp->ma_keys = dict_mp->ma_keys;
73 result_mp->ma_used = dict_mp->ma_used;
79 dict_mp->ma_keys->dk_refcnt += 1;
81 for (Py_ssize_t i = 0; i < size; i++) {
82 if (DK_VALUE(dict_mp, i)) {
83 PyObject *value = DK_VALUE(dict_mp, i);
85 DK_VALUE(result_mp, i) = value;
89 DK_VALUE(result_mp, i) = NULL;
93 Nuitka_GC_Track(result_mp);
95#if PYTHON_VERSION >= 0x360
99 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
100 assert(dict_mp->ma_values == NULL);
101 assert(dict_mp->ma_keys->dk_refcnt == 1);
103 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
104 result = (PyObject *)result_mp;
106 result_mp->ma_values = NULL;
107 result_mp->ma_used = dict_mp->ma_used;
109 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
110 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
111 assert(result_mp->ma_keys);
113 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
116#if PYTHON_VERSION < 0x3b0
117 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
118 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
120 for (Py_ssize_t i = 0; i < size; i++) {
121 PyDictKeyEntry *entry = &entries[i];
122 PyObject *value = entry->me_value;
125 PyObject *key = entry->me_key;
133 PyObject **key_ptr, **value_ptr;
136 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
139 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
141 key_ptr = &ep0->me_key;
142 value_ptr = &ep0->me_value;
143 entry_size =
sizeof(PyDictUnicodeEntry) /
sizeof(PyObject *);
145 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
147 key_ptr = &ep0->me_key;
148 value_ptr = &ep0->me_value;
149 entry_size =
sizeof(PyDictKeyEntry) /
sizeof(PyObject *);
152 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
154 for (Py_ssize_t i = 0; i < size; i++) {
155 PyObject *value = *value_ptr;
160 PyObject *key = *key_ptr;
164 value_ptr += entry_size;
165 key_ptr += entry_size;
174 Nuitka_GC_Track(result_mp);
178 result = _PyDict_NewPresized(dict_mp->ma_used);
180#if PYTHON_VERSION < 0x3b0
181 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
183 for (Py_ssize_t i = 0; i < size; i++) {
184 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
185 PyObject *value = entry->me_value;
188 PyObject *key = entry->me_key;
193 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
199 PyObject *key, *value;
201 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
207 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
215 Py_END_CRITICAL_SECTION();
220PyObject *DEEP_COPY_DICT(PyThreadState *tstate, PyObject *dict_value) {
223#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
224 CHECK_OBJECT(dict_value);
225 assert(PyDict_CheckExact(dict_value));
227 result = DICT_COPY(tstate, dict_value);
230 PyObject *key, *value;
232 while (Nuitka_DictNext(dict_value, &pos, &key, &value)) {
233 PyObject *dict_value_copy = DEEP_COPY(tstate, value);
235 if (dict_value_copy != value) {
236 DICT_SET_ITEM(result, key, value);
240 Py_BEGIN_CRITICAL_SECTION(dict_value);
242 CHECK_OBJECT(dict_value);
243 assert(PyDict_CheckExact(dict_value));
245 if (((PyDictObject *)dict_value)->ma_used == 0) {
246 result = MAKE_DICT_EMPTY(tstate);
248 PyDictObject *dict_mp = (PyDictObject *)dict_value;
250#if PYTHON_VERSION < 0x300
253 result = _PyDict_NewPresized(dict_mp->ma_used);
255 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
256 PyDictEntry *entry = &dict_mp->ma_table[i];
258 if (entry->me_value != NULL) {
259 PyObject *key = entry->me_key;
261 PyObject *value = entry->me_value;
262 value = DEEP_COPY(tstate, value);
264 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
272 if (_PyDict_HasSplitTable(dict_mp)) {
273 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
274 assert(result_mp != NULL);
275 result = (PyObject *)result_mp;
277#if PYTHON_VERSION < 0x3b0
278 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
280 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
283#if PYTHON_VERSION < 0x3d0
284 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
285 assert(new_values != NULL);
287#if PYTHON_VERSION >= 0x3b0
289 size_t prefix_size = ((uint8_t *)new_values)[-1];
290 memcpy((
char *)new_values - prefix_size, (
char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
293 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
296 result_mp->ma_values = new_values;
297 result_mp->ma_keys = dict_mp->ma_keys;
298 result_mp->ma_used = dict_mp->ma_used;
304 dict_mp->ma_keys->dk_refcnt += 1;
306 for (Py_ssize_t i = 0; i < size; i++) {
307 if (DK_VALUE(dict_mp, i)) {
308 PyObject *value = DK_VALUE(dict_mp, i);
309 value = DEEP_COPY(tstate, value);
311 DK_VALUE(result_mp, i) = value;
314 DK_VALUE(result_mp, i) = NULL;
318 Nuitka_GC_Track(result_mp);
320#if PYTHON_VERSION >= 0x360
324 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
325 assert(dict_mp->ma_values == NULL);
326 assert(dict_mp->ma_keys->dk_refcnt == 1);
328 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
329 result = (PyObject *)result_mp;
331 result_mp->ma_values = NULL;
332 result_mp->ma_used = dict_mp->ma_used;
334 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
335 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
336 assert(result_mp->ma_keys);
338 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
341#if PYTHON_VERSION < 0x3b0
342 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
343 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
345 for (Py_ssize_t i = 0; i < size; i++) {
346 PyDictKeyEntry *entry = &entries[i];
347 PyObject *value = entry->me_value;
350 PyObject *key = entry->me_key;
354 value = DEEP_COPY(tstate, value);
356 entry->me_value = value;
360 PyObject **key_ptr, **value_ptr;
363 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
366 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
368 key_ptr = &ep0->me_key;
369 value_ptr = &ep0->me_value;
370 entry_size =
sizeof(PyDictUnicodeEntry) /
sizeof(PyObject *);
372 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
374 key_ptr = &ep0->me_key;
375 value_ptr = &ep0->me_value;
376 entry_size =
sizeof(PyDictKeyEntry) /
sizeof(PyObject *);
379 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
381 for (Py_ssize_t i = 0; i < size; i++) {
382 PyObject *value = *value_ptr;
385 value = DEEP_COPY(tstate, value);
387 PyObject *key = *key_ptr;
391 value_ptr += entry_size;
392 key_ptr += entry_size;
401 Nuitka_GC_Track(result_mp);
405 result = _PyDict_NewPresized(dict_mp->ma_used);
407#if PYTHON_VERSION < 0x3b0
408 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
410 for (Py_ssize_t i = 0; i < size; i++) {
411 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
412 PyObject *value = entry->me_value;
415 PyObject *key = entry->me_key;
420 value = DEEP_COPY(tstate, value);
422 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
430 PyObject *key, *value;
432 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
438 value = DEEP_COPY(tstate, value);
440 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
450 Py_END_CRITICAL_SECTION();
457static PyObject *COPY_DICT_KW(PyThreadState *tstate, PyObject *dict_value) {
459 bool had_kw_error =
false;
461#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
462 CHECK_OBJECT(dict_value);
463 assert(PyDict_CheckExact(dict_value));
465 result = DICT_COPY(tstate, dict_value);
468 PyObject *key, *value;
470 while (Nuitka_DictNext(dict_value, &pos, &key, &value)) {
471 if (unlikely(!checkKeywordType(key))) {
476 Py_BEGIN_CRITICAL_SECTION(dict_value);
478 CHECK_OBJECT(dict_value);
479 assert(PyDict_CheckExact(dict_value));
481 if (((PyDictObject *)dict_value)->ma_used == 0) {
482 result = MAKE_DICT_EMPTY(tstate);
484 PyDictObject *dict_mp = (PyDictObject *)dict_value;
486#if PYTHON_VERSION < 0x300
489 result = _PyDict_NewPresized(dict_mp->ma_used);
491 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
492 PyDictEntry *entry = &dict_mp->ma_table[i];
494 if (entry->me_value != NULL) {
495 PyObject *key = entry->me_key;
496 if (unlikely(!checkKeywordType(key))) {
500 PyObject *value = entry->me_value;
502 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
508 if (_PyDict_HasSplitTable(dict_mp)) {
509 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
510 assert(result_mp != NULL);
511 result = (PyObject *)result_mp;
513#if PYTHON_VERSION < 0x3b0
514 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
516 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
518#if PYTHON_VERSION < 0x3b0
519 for (Py_ssize_t i = 0; i < size; i++) {
520 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
522 if (entry->me_value != NULL) {
523 PyObject *key = entry->me_key;
524 if (unlikely(!checkKeywordType(key))) {
530 PyObject *key, *_value;
532 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &_value)) {
534 CHECK_OBJECT(_value);
536 if (unlikely(!checkKeywordType(key))) {
542#if PYTHON_VERSION < 0x3d0
543 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
544 assert(new_values != NULL);
546#if PYTHON_VERSION >= 0x3b0
548 size_t prefix_size = ((uint8_t *)new_values)[-1];
549 memcpy((
char *)new_values - prefix_size, (
char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
552 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
555 result_mp->ma_values = new_values;
556 result_mp->ma_keys = dict_mp->ma_keys;
557 result_mp->ma_used = dict_mp->ma_used;
563 dict_mp->ma_keys->dk_refcnt += 1;
565 for (Py_ssize_t i = 0; i < size; i++) {
566 if (DK_VALUE(dict_mp, i)) {
567 PyObject *value = DK_VALUE(dict_mp, i);
569 DK_VALUE(result_mp, i) = value;
573 DK_VALUE(result_mp, i) = NULL;
577 Nuitka_GC_Track(result_mp);
579#if PYTHON_VERSION >= 0x360
583 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
584 assert(dict_mp->ma_values == NULL);
585 assert(dict_mp->ma_keys->dk_refcnt == 1);
587 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
588 result = (PyObject *)result_mp;
590 result_mp->ma_values = NULL;
591 result_mp->ma_used = dict_mp->ma_used;
593 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
594 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
595 assert(result_mp->ma_keys);
597 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
600#if PYTHON_VERSION < 0x3b0
601 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
602 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
604 for (Py_ssize_t i = 0; i < size; i++) {
605 PyDictKeyEntry *entry = &entries[i];
606 PyObject *value = entry->me_value;
609 PyObject *key = entry->me_key;
610 if (unlikely(!checkKeywordType(key))) {
619 PyObject **key_ptr, **value_ptr;
622 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
625 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
627 key_ptr = &ep0->me_key;
628 value_ptr = &ep0->me_value;
629 entry_size =
sizeof(PyDictUnicodeEntry) /
sizeof(PyObject *);
631 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
633 key_ptr = &ep0->me_key;
634 value_ptr = &ep0->me_value;
635 entry_size =
sizeof(PyDictKeyEntry) /
sizeof(PyObject *);
638 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
640 for (Py_ssize_t i = 0; i < size; i++) {
641 PyObject *value = *value_ptr;
646 PyObject *key = *key_ptr;
647 if (is_unicode ==
false) {
648 if (unlikely(!checkKeywordType(key))) {
655 value_ptr += entry_size;
656 key_ptr += entry_size;
665 Nuitka_GC_Track(result_mp);
669 result = _PyDict_NewPresized(dict_mp->ma_used);
671#if PYTHON_VERSION < 0x3b0
672 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
674 for (Py_ssize_t i = 0; i < size; i++) {
675 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
676 PyObject *value = entry->me_value;
679 PyObject *key = entry->me_key;
682 if (unlikely(!checkKeywordType(key))) {
688 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
694 PyObject *key, *value;
696 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
700 if (unlikely(!checkKeywordType(key))) {
706 NUITKA_MAY_BE_UNUSED
int res = PyDict_SetItem(result, key, value);
714 Py_END_CRITICAL_SECTION();
717 if (unlikely(had_kw_error)) {