10#include "nuitka/prelude.h"
13#if PYTHON_VERSION >= 0x390
15 PyObject_HEAD PyObject *origin;
21typedef PyObject *(*copy_func)(PyThreadState *tstate, PyObject *);
23static PyObject *DEEP_COPY_ITEM(PyThreadState *tstate, PyObject *value, PyTypeObject **type, copy_func *copy_function);
25PyObject *DEEP_COPY_LIST(PyThreadState *tstate, PyObject *value) {
26 assert(PyList_CheckExact(value));
28 Py_ssize_t n = PyList_GET_SIZE(value);
29 PyObject *result = MAKE_LIST_EMPTY(tstate, n);
31 PyTypeObject *type = NULL;
32 copy_func copy_function = NULL;
34 for (Py_ssize_t i = 0; i < n; i++) {
35 PyObject *item = PyList_GET_ITEM(value, i);
37 PyList_SET_ITEM(result, i, DEEP_COPY_ITEM(tstate, item, &type, ©_function));
41 if (likely(type == Py_TYPE(item))) {
43 new_item = copy_function(tstate, item);
49 new_item = DEEP_COPY_ITEM(tstate, item, &type, ©_function);
52 PyList_SET_ITEM(result, i, new_item);
59PyObject *DEEP_COPY_TUPLE(PyThreadState *tstate, PyObject *value) {
60 assert(PyTuple_CheckExact(value));
62 Py_ssize_t n = PyTuple_GET_SIZE(value);
64 PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, n);
66 for (Py_ssize_t i = 0; i < n; i++) {
67 PyTuple_SET_ITEM(result, i, DEEP_COPY(tstate, PyTuple_GET_ITEM(value, i)));
73static PyObject *_DEEP_COPY_SET(PyObject *value) {
76 return PySet_New(value);
79PyObject *DEEP_COPY_SET(PyThreadState *tstate, PyObject *value) {
return _DEEP_COPY_SET(value); }
81#if PYTHON_VERSION >= 0x390
82PyObject *DEEP_COPY_GENERICALIAS(PyThreadState *tstate, PyObject *value) {
83 assert(Py_TYPE(value) == &Py_GenericAliasType);
85 GenericAliasObject *generic_alias = (GenericAliasObject *)value;
87 PyObject *args = DEEP_COPY(tstate, generic_alias->args);
88 PyObject *origin = DEEP_COPY(tstate, generic_alias->origin);
90 if (generic_alias->args == args && generic_alias->origin == origin) {
94 return Py_GenericAlias(origin, args);
99static PyObject *_deep_copy_dispatch = NULL;
100static PyObject *_deep_noop = NULL;
102static PyObject *Nuitka_CapsuleNew(
void *pointer) {
103#if PYTHON_VERSION < 0x300
104 return PyCObject_FromVoidPtr(pointer, NULL);
106 return PyCapsule_New(pointer,
"", NULL);
110#if PYTHON_VERSION >= 0x300
112 PyObject_HEAD
void *pointer;
115 PyCapsule_Destructor destructor;
118#define Nuitka_CapsuleGetPointer(capsule) (((Nuitka_PyCapsule *)(capsule))->pointer)
121#define Nuitka_CapsuleGetPointer(capsule) (PyCObject_AsVoidPtr(capsule))
124#if PYTHON_VERSION >= 0x3a0
125PyTypeObject *Nuitka_PyUnion_Type;
128static PyObject *_makeDeepCopyFunctionCapsule(copy_func func) {
return Nuitka_CapsuleNew((
void *)func); }
130static void _initDeepCopy(
void) {
131 _deep_copy_dispatch = PyDict_New();
132 _deep_noop = Py_None;
134 CHECK_OBJECT(_deep_noop);
136 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyDict_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_DICT));
137 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyList_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_LIST));
138 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyTuple_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_TUPLE));
139 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PySet_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_SET));
140 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyByteArray_Type, _makeDeepCopyFunctionCapsule(BYTEARRAY_COPY));
142#if PYTHON_VERSION >= 0x390
143 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&Py_GenericAliasType,
144 _makeDeepCopyFunctionCapsule(DEEP_COPY_GENERICALIAS));
147#if PYTHON_VERSION >= 0x3a0
149 PyThreadState *tstate = PyThreadState_GET();
151 PyObject *args[2] = {(PyObject *)&PyFloat_Type, (PyObject *)&PyTuple_Type};
152 PyObject *args_tuple = MAKE_TUPLE(tstate, args, 2);
153 PyObject *union_value = MAKE_UNION_TYPE(args_tuple);
155 Nuitka_PyUnion_Type = Py_TYPE(union_value);
157 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Nuitka_PyUnion_Type, _deep_noop);
159 Py_DECREF(union_value);
160 Py_DECREF(args_tuple);
165#if PYTHON_VERSION < 0x300
166 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyString_Type, _deep_noop);
167 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyInt_Type, _deep_noop);
169 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyBytes_Type, _deep_noop);
171 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyUnicode_Type, _deep_noop);
172 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyLong_Type, _deep_noop);
173 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_None), _deep_noop);
174 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyBool_Type, _deep_noop);
175 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyFloat_Type, _deep_noop);
176 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyRange_Type, _deep_noop);
177 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyType_Type, _deep_noop);
178 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PySlice_Type, _deep_noop);
179 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyComplex_Type, _deep_noop);
180 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyCFunction_Type, _deep_noop);
181 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_Ellipsis), _deep_noop);
182 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_NotImplemented), _deep_noop);
185 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyFrozenSet_Type, _deep_noop);
188static PyObject *DEEP_COPY_ITEM(PyThreadState *tstate, PyObject *value, PyTypeObject **type, copy_func *copy_function) {
189 *type = Py_TYPE(value);
191 PyObject *dispatcher = DICT_GET_ITEM0(tstate, _deep_copy_dispatch, (PyObject *)*type);
193 if (unlikely(dispatcher == NULL)) {
194 NUITKA_CANNOT_GET_HERE(
"DEEP_COPY encountered unknown type");
197 if (dispatcher == Py_None) {
198 *copy_function = NULL;
203 *copy_function = (copy_func)(Nuitka_CapsuleGetPointer(dispatcher));
204 return (*copy_function)(tstate, value);
208PyObject *DEEP_COPY(PyThreadState *tstate, PyObject *value) {
210 PyObject *dispatcher = DICT_GET_ITEM0(tstate, _deep_copy_dispatch, (PyObject *)Py_TYPE(value));
212 if (unlikely(dispatcher == NULL)) {
213 NUITKA_CANNOT_GET_HERE(
"DEEP_COPY encountered unknown type");
216 if (dispatcher == Py_None) {
220 copy_func copy_function = (copy_func)(Nuitka_CapsuleGetPointer(dispatcher));
221 return copy_function(tstate, value);
226 if (PyDict_CheckExact(value)) {
227 return DEEP_COPY_DICT(value);
228 }
else if (PyList_CheckExact(value)) {
229 return DEEP_COPY_LIST(value);
230 }
else if (PyTuple_CheckExact(value)) {
231 return DEEP_COPY_TUPLE(value);
232 }
else if (PySet_CheckExact(value)) {
233 return DEEP_COPY_SET(value);
234 }
else if (PyFrozenSet_CheckExact(value)) {
239#
if PYTHON_VERSION < 0x300
240 PyString_Check(value) ||
242 PyUnicode_Check(value) ||
243#
if PYTHON_VERSION < 0x300
244 PyInt_CheckExact(value) ||
246 PyLong_CheckExact(value) || value == Py_None || PyBool_Check(value) || PyFloat_CheckExact(value) ||
247 PyBytes_CheckExact(value) || PyRange_Check(value) || PyType_Check(value) || PySlice_Check(value) ||
248 PyComplex_CheckExact(value) || PyCFunction_Check(value) || value == Py_Ellipsis || value == Py_NotImplemented) {
251 }
else if (PyByteArray_CheckExact(value)) {
253 return PyByteArray_FromObject(value);
254#if PYTHON_VERSION >= 0x390
255 }
else if (Py_TYPE(value) == &Py_GenericAliasType) {
256 GenericAliasObject *generic_alias = (GenericAliasObject *)value;
258 PyObject *args = DEEP_COPY(generic_alias->args);
259 PyObject *origin = DEEP_COPY(generic_alias->origin);
261 if (generic_alias->args == args && generic_alias->origin == origin) {
265 return Py_GenericAlias(origin, args);
269 NUITKA_CANNOT_GET_HERE(
"DEEP_COPY encountered unknown type");
274#ifndef __NUITKA_NO_ASSERT__
276static Py_hash_t DEEP_HASH_INIT(PyThreadState *tstate, PyObject *value) {
279 size_t value2 = (size_t)value;
280 Py_hash_t result = (Py_hash_t)(value2);
282 if (Py_TYPE(value) != &PyType_Type) {
283 result ^= DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
289static void DEEP_HASH_BLOB(Py_hash_t *hash,
char const *s, Py_ssize_t size) {
291 *hash = (1000003 * (*hash)) ^ (Py_hash_t)(*s++);
296static void DEEP_HASH_CSTR(Py_hash_t *hash,
char const *s) { DEEP_HASH_BLOB(hash, s, strlen(s)); }
300Py_hash_t DEEP_HASH(PyThreadState *tstate, PyObject *value) {
301 assert(value != NULL);
303 if (PyType_Check(value)) {
304 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
306 DEEP_HASH_CSTR(&result, ((PyTypeObject *)value)->tp_name);
308 }
else if (PyDict_Check(value)) {
309 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
312 PyObject *key, *dict_value;
314 while (Nuitka_DictNext(value, &pos, &key, &dict_value)) {
315 if (key != NULL && value != NULL) {
316 result ^= DEEP_HASH(tstate, key);
317 result ^= DEEP_HASH(tstate, dict_value);
322 }
else if (PyTuple_Check(value)) {
323 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
325 Py_ssize_t n = PyTuple_GET_SIZE(value);
327 for (Py_ssize_t i = 0; i < n; i++) {
328 result ^= DEEP_HASH(tstate, PyTuple_GET_ITEM(value, i));
332 }
else if (PyList_CheckExact(value)) {
333 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
335 Py_ssize_t n = PyList_GET_SIZE(value);
337 for (Py_ssize_t i = 0; i < n; i++) {
338 result ^= DEEP_HASH(tstate, PyList_GET_ITEM(value, i));
342 }
else if (PySet_Check(value) || PyFrozenSet_Check(value)) {
343 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
345 PyObject *iterator = PyObject_GetIter(value);
346 CHECK_OBJECT(iterator);
349 PyObject *item = PyIter_Next(iterator);
355 result ^= DEEP_HASH(tstate, item);
363 }
else if (PyLong_Check(value)) {
364 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
368 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
372 PyObject *str = PyObject_Str(value);
373 result ^= DEEP_HASH(tstate, str);
376 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
379 }
else if (PyUnicode_Check(value)) {
380 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
384 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
386#if PYTHON_VERSION >= 0x300
387 char const *s = (
char const *)PyUnicode_DATA(value);
388 Py_ssize_t size = PyUnicode_GET_LENGTH(value) * PyUnicode_KIND(value);
390 DEEP_HASH_BLOB(&result, s, size);
392 PyObject *str = PyUnicode_AsUTF8String(value);
395 result ^= DEEP_HASH(tstate, str);
400 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
404#if PYTHON_VERSION < 0x300
405 else if (PyString_Check(value)) {
406 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
411 int res = PyString_AsStringAndSize(value, &s, &size);
414 DEEP_HASH_BLOB(&result, s, size);
419 else if (PyBytes_Check(value)) {
420 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
425 int res = PyBytes_AsStringAndSize(value, &s, &size);
428 DEEP_HASH_BLOB(&result, s, size);
433 else if (PyByteArray_Check(value)) {
434 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
436 Py_ssize_t size = PyByteArray_Size(value);
439 char *s = PyByteArray_AsString(value);
441 DEEP_HASH_BLOB(&result, s, size);
444 }
else if (value == Py_None || value == Py_Ellipsis || value == Py_NotImplemented) {
445 return DEEP_HASH_INIT(tstate, value);
446 }
else if (PyComplex_Check(value)) {
447 Py_complex c = PyComplex_AsCComplex(value);
449 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
451 Py_ssize_t size =
sizeof(c);
452 char *s = (
char *)&c;
454 DEEP_HASH_BLOB(&result, s, size);
457 }
else if (PyFloat_Check(value)) {
458 double f = PyFloat_AsDouble(value);
460 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
462 Py_ssize_t size =
sizeof(f);
463 char *s = (
char *)&f;
465 DEEP_HASH_BLOB(&result, s, size);
469#
if PYTHON_VERSION < 0x300
470 PyInt_Check(value) ||
472 PyBool_Check(value) || PyRange_Check(value) || PySlice_Check(value) || PyCFunction_Check(value)) {
473 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
476 printf(
"Too simple deep hash: %s\n", Py_TYPE(value)->tp_name);
480#if PYTHON_VERSION >= 0x390
481 }
else if (Py_TYPE(value) == &Py_GenericAliasType) {
482 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
484 GenericAliasObject *generic_alias = (GenericAliasObject *)value;
486 result ^= DEEP_HASH(tstate, generic_alias->args);
487 result ^= DEEP_HASH(tstate, generic_alias->origin);
491#if PYTHON_VERSION >= 0x3a0
492 }
else if (Py_TYPE(value) == Nuitka_PyUnion_Type) {
493 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
495 result ^= DEEP_HASH(tstate, LOOKUP_ATTRIBUTE(tstate, value, const_str_plain___args__));
499 }
else if (PyCode_Check(value)) {
500 return DEEP_HASH_INIT(tstate, value);
502 NUITKA_CANNOT_GET_HERE(
"Unknown type hashed");
510void CHECK_OBJECT_DEEP(PyObject *value) {
513 if (PyTuple_Check(value)) {
514 for (Py_ssize_t i = 0, size = PyTuple_GET_SIZE(value); i < size; i++) {
515 PyObject *element = PyTuple_GET_ITEM(value, i);
517 CHECK_OBJECT_DEEP(element);
519 }
else if (PyList_CheckExact(value)) {
520 for (Py_ssize_t i = 0, size = PyList_GET_SIZE(value); i < size; i++) {
521 PyObject *element = PyList_GET_ITEM(value, i);
523 CHECK_OBJECT_DEEP(element);
525 }
else if (PyDict_Check(value)) {
527 PyObject *dict_key, *dict_value;
529 while (Nuitka_DictNext(value, &pos, &dict_key, &dict_value)) {
530 CHECK_OBJECT_DEEP(dict_key);
531 CHECK_OBJECT_DEEP(dict_value);
536void CHECK_OBJECTS_DEEP(PyObject *
const *values, Py_ssize_t size) {
537 for (Py_ssize_t i = 0; i < size; i++) {
538 CHECK_OBJECT_DEEP(values[i]);
542static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
543static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
545static PyObject *_DEEP_COPY_ELEMENT_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
554 return _DEEP_COPY_LIST_GUIDED(tstate, value, guide);
556 return LIST_COPY(tstate, value);
558 return _DEEP_COPY_TUPLE_GUIDED(tstate, value, guide);
560 return TUPLE_COPY(tstate, value);
562 return DEEP_COPY_DICT(tstate, value);
564 return DICT_COPY(tstate, value);
566 return DEEP_COPY_SET(tstate, value);
568 return BYTEARRAY_COPY(tstate, value);
570 return DEEP_COPY(tstate, value);
572 NUITKA_CANNOT_GET_HERE(
"Illegal type guide");
577static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
578 assert(PyList_CheckExact(value));
580 Py_ssize_t size = PyList_GET_SIZE(value);
582 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
584 for (Py_ssize_t i = 0; i < size; i++) {
585 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyList_GET_ITEM(value, i), guide);
587 PyList_SET_ITEM(result, i, item);
593static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
594 assert(PyTuple_CheckExact(value));
596 Py_ssize_t size = PyTuple_GET_SIZE(value);
600 PyObject *result = MAKE_TUPLE_EMPTY(tstate, size);
602 for (Py_ssize_t i = 0; i < size; i++) {
603 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyTuple_GET_ITEM(value, i), guide);
605 PyTuple_SET_ITEM(result, i, item);
611PyObject *DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
612 PyObject *result = _DEEP_COPY_LIST_GUIDED(tstate, value, &guide);
617PyObject *DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
618 PyObject *result = _DEEP_COPY_TUPLE_GUIDED(tstate, value, &guide);
Definition exceptions.h:712