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(PyThreadState *tstate) {
132 assert(_deep_copy_dispatch == NULL);
134 _deep_copy_dispatch = PyDict_New();
135 _deep_noop = Py_None;
137 CHECK_OBJECT(_deep_noop);
139 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyDict_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_DICT));
140 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyList_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_LIST));
141 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyTuple_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_TUPLE));
142 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PySet_Type, _makeDeepCopyFunctionCapsule(DEEP_COPY_SET));
143 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyByteArray_Type, _makeDeepCopyFunctionCapsule(BYTEARRAY_COPY));
145#if PYTHON_VERSION >= 0x390
146 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&Py_GenericAliasType,
147 _makeDeepCopyFunctionCapsule(DEEP_COPY_GENERICALIAS));
150#if PYTHON_VERSION >= 0x3a0
152 PyObject *args[2] = {(PyObject *)&PyFloat_Type, (PyObject *)&PyTuple_Type};
153 PyObject *args_tuple = MAKE_TUPLE(tstate, args, 2);
154 PyObject *union_value = MAKE_UNION_TYPE(args_tuple);
156 Nuitka_PyUnion_Type = Py_TYPE(union_value);
158 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Nuitka_PyUnion_Type, _deep_noop);
160 Py_DECREF(union_value);
161 Py_DECREF(args_tuple);
166#if PYTHON_VERSION < 0x300
167 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyString_Type, _deep_noop);
168 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyInt_Type, _deep_noop);
170 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyBytes_Type, _deep_noop);
172 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyUnicode_Type, _deep_noop);
173 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyLong_Type, _deep_noop);
174 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_None), _deep_noop);
175 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyBool_Type, _deep_noop);
176 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyFloat_Type, _deep_noop);
177 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyRange_Type, _deep_noop);
178 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyType_Type, _deep_noop);
179 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PySlice_Type, _deep_noop);
180 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyComplex_Type, _deep_noop);
181 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyCFunction_Type, _deep_noop);
182 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_Ellipsis), _deep_noop);
183 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)Py_TYPE(Py_NotImplemented), _deep_noop);
186 PyDict_SetItem(_deep_copy_dispatch, (PyObject *)&PyFrozenSet_Type, _deep_noop);
189static PyObject *DEEP_COPY_ITEM(PyThreadState *tstate, PyObject *value, PyTypeObject **type, copy_func *copy_function) {
190 *type = Py_TYPE(value);
192 PyObject *dispatcher = DICT_GET_ITEM0(tstate, _deep_copy_dispatch, (PyObject *)*type);
194 if (unlikely(dispatcher == NULL)) {
195 NUITKA_CANNOT_GET_HERE(
"DEEP_COPY encountered unknown type");
198 if (dispatcher == Py_None) {
199 *copy_function = NULL;
204 *copy_function = (copy_func)(Nuitka_CapsuleGetPointer(dispatcher));
205 return (*copy_function)(tstate, value);
209PyObject *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);
225#ifndef __NUITKA_NO_ASSERT__
227static Py_hash_t DEEP_HASH_INIT(PyThreadState *tstate, PyObject *value) {
230 size_t value2 = (size_t)value;
231 Py_hash_t result = (Py_hash_t)(value2);
233 if (Py_TYPE(value) != &PyType_Type) {
234 result ^= DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
240static void DEEP_HASH_BLOB(Py_hash_t *hash,
char const *s, Py_ssize_t size) {
242 *hash = (1000003 * (*hash)) ^ (Py_hash_t)(*s++);
247static void DEEP_HASH_CSTR(Py_hash_t *hash,
char const *s) { DEEP_HASH_BLOB(hash, s, strlen(s)); }
251Py_hash_t DEEP_HASH(PyThreadState *tstate, PyObject *value) {
252 assert(value != NULL);
254 if (PyType_Check(value)) {
255 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
257 DEEP_HASH_CSTR(&result, ((PyTypeObject *)value)->tp_name);
259 }
else if (PyDict_Check(value)) {
260 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
263 PyObject *key, *dict_value;
265 while (Nuitka_DictNext(value, &pos, &key, &dict_value)) {
266 if (key != NULL && value != NULL) {
267 result ^= DEEP_HASH(tstate, key);
268 result ^= DEEP_HASH(tstate, dict_value);
273 }
else if (PyTuple_Check(value)) {
274 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
276 Py_ssize_t n = PyTuple_GET_SIZE(value);
278 for (Py_ssize_t i = 0; i < n; i++) {
279 result ^= DEEP_HASH(tstate, PyTuple_GET_ITEM(value, i));
283 }
else if (PyList_CheckExact(value)) {
284 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
286 Py_ssize_t n = PyList_GET_SIZE(value);
288 for (Py_ssize_t i = 0; i < n; i++) {
289 result ^= DEEP_HASH(tstate, PyList_GET_ITEM(value, i));
293 }
else if (PySet_Check(value) || PyFrozenSet_Check(value)) {
294 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
296 PyObject *iterator = PyObject_GetIter(value);
297 CHECK_OBJECT(iterator);
300 PyObject *item = PyIter_Next(iterator);
306 result ^= DEEP_HASH(tstate, item);
314 }
else if (PyLong_Check(value)) {
315 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
319 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
323 PyObject *str = PyObject_Str(value);
324 result ^= DEEP_HASH(tstate, str);
327 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
330 }
else if (PyUnicode_Check(value)) {
331 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
335 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
337#if PYTHON_VERSION >= 0x300
338 char const *s = (
char const *)PyUnicode_DATA(value);
339 Py_ssize_t size = PyUnicode_GET_LENGTH(value) * PyUnicode_KIND(value);
341 DEEP_HASH_BLOB(&result, s, size);
343 PyObject *str = PyUnicode_AsUTF8String(value);
346 result ^= DEEP_HASH(tstate, str);
351 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
355#if PYTHON_VERSION < 0x300
356 else if (PyString_Check(value)) {
357 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
362 int res = PyString_AsStringAndSize(value, &s, &size);
365 DEEP_HASH_BLOB(&result, s, size);
370 else if (PyBytes_Check(value)) {
371 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
376 int res = PyBytes_AsStringAndSize(value, &s, &size);
379 DEEP_HASH_BLOB(&result, s, size);
384 else if (PyByteArray_Check(value)) {
385 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
387 Py_ssize_t size = PyByteArray_Size(value);
390 char *s = PyByteArray_AsString(value);
392 DEEP_HASH_BLOB(&result, s, size);
395 }
else if (value == Py_None || value == Py_Ellipsis || value == Py_NotImplemented) {
396 return DEEP_HASH_INIT(tstate, value);
397 }
else if (PyComplex_Check(value)) {
398 Py_complex c = PyComplex_AsCComplex(value);
400 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
402 Py_ssize_t size =
sizeof(c);
403 char *s = (
char *)&c;
405 DEEP_HASH_BLOB(&result, s, size);
408 }
else if (PyFloat_Check(value)) {
409 double f = PyFloat_AsDouble(value);
411 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
413 Py_ssize_t size =
sizeof(f);
414 char *s = (
char *)&f;
416 DEEP_HASH_BLOB(&result, s, size);
420#
if PYTHON_VERSION < 0x300
421 PyInt_Check(value) ||
423 PyBool_Check(value) || PyRange_Check(value) || PySlice_Check(value) || PyCFunction_Check(value)) {
424 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
427 printf(
"Too simple deep hash: %s\n", Py_TYPE(value)->tp_name);
431#if PYTHON_VERSION >= 0x390
432 }
else if (Py_TYPE(value) == &Py_GenericAliasType) {
433 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
435 GenericAliasObject *generic_alias = (GenericAliasObject *)value;
437 result ^= DEEP_HASH(tstate, generic_alias->args);
438 result ^= DEEP_HASH(tstate, generic_alias->origin);
442#if PYTHON_VERSION >= 0x3a0
443 }
else if (Py_TYPE(value) == Nuitka_PyUnion_Type) {
444 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
446 result ^= DEEP_HASH(tstate, LOOKUP_ATTRIBUTE(tstate, value, const_str_plain___args__));
450 }
else if (PyCode_Check(value)) {
451 return DEEP_HASH_INIT(tstate, value);
453 NUITKA_CANNOT_GET_HERE(
"Unknown type hashed");
461void CHECK_OBJECT_DEEP(PyObject *value) {
464 if (PyTuple_Check(value)) {
465 for (Py_ssize_t i = 0, size = PyTuple_GET_SIZE(value); i < size; i++) {
466 PyObject *element = PyTuple_GET_ITEM(value, i);
468 CHECK_OBJECT_DEEP(element);
470 }
else if (PyList_CheckExact(value)) {
471 for (Py_ssize_t i = 0, size = PyList_GET_SIZE(value); i < size; i++) {
472 PyObject *element = PyList_GET_ITEM(value, i);
474 CHECK_OBJECT_DEEP(element);
476 }
else if (PyDict_Check(value)) {
478 PyObject *dict_key, *dict_value;
480 while (Nuitka_DictNext(value, &pos, &dict_key, &dict_value)) {
481 CHECK_OBJECT_DEEP(dict_key);
482 CHECK_OBJECT_DEEP(dict_value);
487void CHECK_OBJECTS_DEEP(PyObject *
const *values, Py_ssize_t size) {
488 for (Py_ssize_t i = 0; i < size; i++) {
489 CHECK_OBJECT_DEEP(values[i]);
493static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
494static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
496static PyObject *_DEEP_COPY_ELEMENT_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
505 return _DEEP_COPY_LIST_GUIDED(tstate, value, guide);
507 return LIST_COPY(tstate, value);
509 return _DEEP_COPY_TUPLE_GUIDED(tstate, value, guide);
511 return TUPLE_COPY(tstate, value);
513 return DEEP_COPY_DICT(tstate, value);
515 return DICT_COPY(tstate, value);
517 return DEEP_COPY_SET(tstate, value);
519 return BYTEARRAY_COPY(tstate, value);
521 return DEEP_COPY(tstate, value);
523 NUITKA_CANNOT_GET_HERE(
"Illegal type guide");
528static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
529 assert(PyList_CheckExact(value));
531 Py_ssize_t size = PyList_GET_SIZE(value);
533 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
535 for (Py_ssize_t i = 0; i < size; i++) {
536 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyList_GET_ITEM(value, i), guide);
538 PyList_SET_ITEM(result, i, item);
544static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
545 assert(PyTuple_CheckExact(value));
547 Py_ssize_t size = PyTuple_GET_SIZE(value);
551 PyObject *result = MAKE_TUPLE_EMPTY(tstate, size);
553 for (Py_ssize_t i = 0; i < size; i++) {
554 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyTuple_GET_ITEM(value, i), guide);
556 PyTuple_SET_ITEM(result, i, item);
562PyObject *DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
563 PyObject *result = _DEEP_COPY_LIST_GUIDED(tstate, value, &guide);
568PyObject *DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
569 PyObject *result = _DEEP_COPY_TUPLE_GUIDED(tstate, value, &guide);
Definition exceptions.h:712