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 && dict_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);
302 assert(!HAS_ERROR_OCCURRED(tstate));
308 result ^= DEEP_HASH(tstate, item);
316 }
else if (PyLong_Check(value)) {
317 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
321 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
325 PyObject *str = PyObject_Str(value);
327 result ^= DEEP_HASH(tstate, str);
330 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
333 }
else if (PyUnicode_Check(value)) {
334 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
338 FETCH_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
340#if PYTHON_VERSION >= 0x300
341 char const *s = (
char const *)PyUnicode_DATA(value);
342 Py_ssize_t size = PyUnicode_GET_LENGTH(value) * PyUnicode_KIND(value);
344 DEEP_HASH_BLOB(&result, s, size);
346 PyObject *str = PyUnicode_AsUTF8String(value);
348 result ^= DEEP_HASH(tstate, str);
352 RESTORE_ERROR_OCCURRED_STATE_UNTRACED(tstate, &saved_exception_state);
356#if PYTHON_VERSION < 0x300
357 else if (PyString_Check(value)) {
358 Py_hash_t result = DEEP_HASH(tstate, (PyObject *)Py_TYPE(value));
363 int res = PyString_AsStringAndSize(value, &s, &size);
366 DEEP_HASH_BLOB(&result, s, size);
371 else if (PyBytes_Check(value)) {
372 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
377 int res = PyBytes_AsStringAndSize(value, &s, &size);
380 DEEP_HASH_BLOB(&result, s, size);
385 else if (PyByteArray_Check(value)) {
386 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
388 Py_ssize_t size = PyByteArray_Size(value);
391 char *s = PyByteArray_AsString(value);
393 DEEP_HASH_BLOB(&result, s, size);
396 }
else if (value == Py_None || value == Py_Ellipsis || value == Py_NotImplemented) {
397 return DEEP_HASH_INIT(tstate, value);
398 }
else if (PyComplex_Check(value)) {
399 Py_complex c = PyComplex_AsCComplex(value);
401 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
403 Py_ssize_t size =
sizeof(c);
404 char *s = (
char *)&c;
406 DEEP_HASH_BLOB(&result, s, size);
409 }
else if (PyFloat_Check(value)) {
410 double f = PyFloat_AsDouble(value);
412 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
414 Py_ssize_t size =
sizeof(f);
415 char *s = (
char *)&f;
417 DEEP_HASH_BLOB(&result, s, size);
421#
if PYTHON_VERSION < 0x300
422 PyInt_Check(value) ||
424 PyBool_Check(value) || PyRange_Check(value) || PySlice_Check(value) || PyCFunction_Check(value)) {
425 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
428 printf(
"Too simple deep hash: %s\n", Py_TYPE(value)->tp_name);
432#if PYTHON_VERSION >= 0x390
433 }
else if (Py_TYPE(value) == &Py_GenericAliasType) {
434 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
436 GenericAliasObject *generic_alias = (GenericAliasObject *)value;
437 CHECK_OBJECT(generic_alias->args);
438 CHECK_OBJECT(generic_alias->origin);
440 result ^= DEEP_HASH(tstate, generic_alias->args);
441 result ^= DEEP_HASH(tstate, generic_alias->origin);
445#if PYTHON_VERSION >= 0x3a0
446 }
else if (Py_TYPE(value) == Nuitka_PyUnion_Type) {
447 Py_hash_t result = DEEP_HASH_INIT(tstate, value);
448 PyObject *args = LOOKUP_ATTRIBUTE(tstate, value, const_str_plain___args__);
451 result ^= DEEP_HASH(tstate, args);
456 }
else if (PyCode_Check(value)) {
457 return DEEP_HASH_INIT(tstate, value);
459 NUITKA_CANNOT_GET_HERE(
"Unknown type hashed");
466static void abortCorruptNamedObject(
char const *name,
char const *reason) {
467 fprintf(stderr,
"Corrupt object at %s: %s\n", name, reason);
472static void abortCorruptNamedRefcount(
char const *name, PyObject *value) {
473 fprintf(stderr,
"Corrupt object at %s: refcount %ld\n", name, (
long)Py_REFCNT(value));
478static void CHECK_OBJECT_TYPE_NAMED(
char const *name, PyObject *value) {
479 char type_name[1024];
480 PyTypeObject *type = Py_TYPE(value);
482 PyOS_snprintf(type_name,
sizeof(type_name),
"%s.__class__", name);
485 abortCorruptNamedObject(type_name,
"NULL");
488 if (Py_REFCNT((PyObject *)type) <= 0) {
489 abortCorruptNamedRefcount(type_name, (PyObject *)type);
493static void CHECK_OBJECT_DEEP_NAMED_RECURSIVE(
char const *name, PyObject *value) {
495 abortCorruptNamedObject(name,
"NULL");
498 if (Py_REFCNT(value) <= 0) {
499 abortCorruptNamedRefcount(name, value);
502 CHECK_OBJECT_TYPE_NAMED(name, value);
504 if (PyTuple_Check(value)) {
505 for (Py_ssize_t i = 0, size = PyTuple_GET_SIZE(value); i < size; i++) {
506 char element_name[1024];
507 PyObject *element = PyTuple_GET_ITEM(value, i);
509 PyOS_snprintf(element_name,
sizeof(element_name),
"%s[%ld]", name, (
long)i);
510 CHECK_OBJECT_DEEP_NAMED_RECURSIVE(element_name, element);
512 }
else if (PyList_CheckExact(value)) {
513 for (Py_ssize_t i = 0, size = PyList_GET_SIZE(value); i < size; i++) {
514 char element_name[1024];
515 PyObject *element = PyList_GET_ITEM(value, i);
517 PyOS_snprintf(element_name,
sizeof(element_name),
"%s[%ld]", name, (
long)i);
518 CHECK_OBJECT_DEEP_NAMED_RECURSIVE(element_name, element);
520 }
else if (PyDict_Check(value)) {
522 PyObject *dict_key, *dict_value;
525 while (Nuitka_DictNext(value, &pos, &dict_key, &dict_value)) {
527 char value_name[1024];
529 PyOS_snprintf(key_name,
sizeof(key_name),
"%s{key %d}", name, item_index);
530 PyOS_snprintf(value_name,
sizeof(value_name),
"%s{value %d}", name, item_index);
532 CHECK_OBJECT_DEEP_NAMED_RECURSIVE(key_name, dict_key);
533 CHECK_OBJECT_DEEP_NAMED_RECURSIVE(value_name, dict_value);
537 }
else if (PySet_Check(value) || PyFrozenSet_Check(value)) {
538 PyObject *iterator = PyObject_GetIter(value);
540 if (iterator == NULL) {
541 abortCorruptNamedObject(name,
"set iteration failed");
544 Py_ssize_t item_index = 0;
547 PyObject *item = PyIter_Next(iterator);
550 if (PyErr_Occurred()) {
552 abortCorruptNamedObject(name,
"set iteration raised");
558 char item_name[1024];
560 PyOS_snprintf(item_name,
sizeof(item_name),
"%s{item %ld}", name, (
long)item_index);
561 CHECK_OBJECT_DEEP_NAMED_RECURSIVE(item_name, item);
572void CHECK_OBJECT_DEEP(PyObject *value) { CHECK_OBJECT_DEEP_NAMED_RECURSIVE(
"<unnamed>", value); }
574void CHECK_OBJECT_DEEP_NAMED(
char const *name, PyObject *value) { CHECK_OBJECT_DEEP_NAMED_RECURSIVE(name, value); }
576void CHECK_OBJECTS_DEEP(PyObject *
const *values, Py_ssize_t size) {
577 for (Py_ssize_t i = 0; i < size; i++) {
578 CHECK_OBJECT_DEEP(values[i]);
582static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
583static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide);
585static PyObject *_DEEP_COPY_ELEMENT_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
594 return _DEEP_COPY_LIST_GUIDED(tstate, value, guide);
596 return LIST_COPY(tstate, value);
598 return _DEEP_COPY_TUPLE_GUIDED(tstate, value, guide);
600 return TUPLE_COPY(tstate, value);
602 return DEEP_COPY_DICT(tstate, value);
604 return DICT_COPY(tstate, value);
606 return DEEP_COPY_SET(tstate, value);
608 return BYTEARRAY_COPY(tstate, value);
610 return DEEP_COPY(tstate, value);
612 NUITKA_CANNOT_GET_HERE(
"Illegal type guide");
617static PyObject *_DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
618 assert(PyList_CheckExact(value));
620 Py_ssize_t size = PyList_GET_SIZE(value);
622 PyObject *result = MAKE_LIST_EMPTY(tstate, size);
624 for (Py_ssize_t i = 0; i < size; i++) {
625 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyList_GET_ITEM(value, i), guide);
627 PyList_SET_ITEM(result, i, item);
633static PyObject *_DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const **guide) {
634 assert(PyTuple_CheckExact(value));
636 Py_ssize_t size = PyTuple_GET_SIZE(value);
640 PyObject *result = MAKE_TUPLE_EMPTY(tstate, size);
642 for (Py_ssize_t i = 0; i < size; i++) {
643 PyObject *item = _DEEP_COPY_ELEMENT_GUIDED(tstate, PyTuple_GET_ITEM(value, i), guide);
645 PyTuple_SET_ITEM(result, i, item);
651PyObject *DEEP_COPY_LIST_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
652 PyObject *result = _DEEP_COPY_LIST_GUIDED(tstate, value, &guide);
657PyObject *DEEP_COPY_TUPLE_GUIDED(PyThreadState *tstate, PyObject *value,
char const *guide) {
658 PyObject *result = _DEEP_COPY_TUPLE_GUIDED(tstate, value, &guide);
Definition exceptions.h:712