Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersConstantsBlob.c
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
12// This file is included from another C file, help IDEs to still parse it on
13// its own.
14#ifdef __IDE_ONLY__
15#include "nuitka/prelude.h"
16
17// Most often used modes per OS, more exist and could be used of course.
18#if defined(_WIN32)
19#define _NUITKA_CONSTANTS_FROM_COFF_OBJ 1
20#elif defined(__APPLE__)
21#define _NUITKA_CONSTANTS_FROM_MACOS_SECTION 1
22#else
23#define _NUITKA_CONSTANTS_FROM_CODE 1
24#endif
25
26#endif
27
28#if _NUITKA_EXPERIMENTAL_WRITEABLE_CONSTANTS
29#define CONSTANT_BIN_CONSTANT
30#else
31#define CONSTANT_BIN_CONSTANT const
32#endif
33
34#if defined(_NUITKA_CONSTANTS_FROM_LINKER) || defined(_NUITKA_CONSTANTS_FROM_COFF_OBJ) || \
35 defined(_NUITKA_CONSTANTS_FROM_CODE) || defined(_NUITKA_CONSTANTS_FROM_INCBIN) || \
36 defined(_NUITKA_CONSTANTS_FROM_C23_EMBED) || defined(_NUITKA_CONSTANTS_FROM_RESOURCE) || \
37 defined(_NUITKA_CONSTANTS_FROM_MACOS_SECTION)
38NUITKA_DECLARE_CONSTANT_BLOB(constant_bin, ConstantBlob, CONSTANT_BIN_CONSTANT, 3);
39#endif
40
41#include "nuitka/constants_blob_spec.h"
42
43// Symbol to be assigned locally.
44unsigned char const *constant_bin = NULL;
45
46#if PYTHON_VERSION < 0x300
47static PyObject *int_cache = NULL;
48#endif
49
50static PyObject *long_cache = NULL;
51
52static PyObject *float_cache = NULL;
53
54#if PYTHON_VERSION >= 0x300
55static PyObject *bytes_cache = NULL;
56#endif
57
58#if PYTHON_VERSION < 0x300
59static PyObject *unicode_cache = NULL;
60#endif
61
62static PyObject *tuple_cache = NULL;
63
64static PyObject *list_cache = NULL;
65
66static PyObject *dict_cache = NULL;
67
68static PyObject *set_cache = NULL;
69
70static PyObject *frozenset_cache = NULL;
71
72// Use our own non-random hash for some of the things to be fast. This is inspired
73// from the original Python2 hash func, but we are mostly using it on pointer values
74static Py_hash_t Nuitka_FastHashBytes(const void *value, Py_ssize_t size) {
75 if (unlikely(size == 0)) {
76 return 0;
77 }
78
79 unsigned char *w = (unsigned char *)value;
80 long x = *w << 7;
81
82 while (--size >= 0) {
83 x = (1000003 * x) ^ *w++;
84 }
85
86 x ^= size;
87
88 // The value -1 is reserved for errors.
89 if (x == -1) {
90 x = -2;
91 }
92
93 return x;
94}
95
96static Py_hash_t our_list_hash(PyListObject *list) {
97 return Nuitka_FastHashBytes(&list->ob_item[0], Py_SIZE(list) * sizeof(PyObject *));
98}
99
100static PyObject *our_list_tp_richcompare(PyListObject *list1, PyListObject *list2, int op) {
101 assert(op == Py_EQ);
102
103 PyObject *result;
104
105 if (list1 == list2) {
106 result = Py_True;
107 } else if (Py_SIZE(list1) != Py_SIZE(list2)) {
108 result = Py_False;
109 } else if (memcmp(&list1->ob_item[0], &list2->ob_item[0], Py_SIZE(list1) * sizeof(PyObject *)) == 0) {
110 result = Py_True;
111 } else {
112 result = Py_False;
113 }
114
115 Py_INCREF_IMMORTAL(result);
116 return result;
117}
118
119static Py_hash_t our_tuple_hash(PyTupleObject *tuple) {
120 return Nuitka_FastHashBytes(&tuple->ob_item[0], Py_SIZE(tuple) * sizeof(PyObject *));
121}
122
123static PyObject *our_tuple_tp_richcompare(PyTupleObject *tuple1, PyTupleObject *tuple2, int op) {
124 assert(op == Py_EQ);
125
126 PyObject *result;
127
128 if (tuple1 == tuple2) {
129 result = Py_True;
130 } else if (Py_SIZE(tuple1) != Py_SIZE(tuple2)) {
131 result = Py_False;
132 } else if (memcmp(&tuple1->ob_item[0], &tuple2->ob_item[0], Py_SIZE(tuple1) * sizeof(PyObject *)) == 0) {
133 result = Py_True;
134 } else {
135 result = Py_False;
136 }
137
138 Py_INCREF_IMMORTAL(result);
139 return result;
140}
141
142static Py_hash_t our_set_hash(PyObject *set) {
143 Py_hash_t result = 0;
144 PyObject *key;
145 Py_ssize_t pos = 0;
146
147#if PYTHON_VERSION < 0x300
148 // Same sized set, simply check if values are identical. Other reductions should
149 // make it identical, or else this won't have the effect intended.
150 while (_PySet_Next(set, &pos, &key)) {
151 result *= 1000003;
152 result ^= Nuitka_FastHashBytes(&key, sizeof(PyObject *));
153 }
154#else
155 Py_hash_t unused;
156
157 while (_PySet_NextEntry(set, &pos, &key, &unused)) {
158 result *= 1000003;
159 result ^= Nuitka_FastHashBytes(&key, sizeof(PyObject *));
160 }
161#endif
162
163 return result;
164}
165
166static PyObject *our_set_tp_richcompare(PyObject *set1, PyObject *set2, int op) {
167 assert(op == Py_EQ);
168
169 PyObject *result;
170
171 Py_ssize_t pos1 = 0, pos2 = 0;
172 PyObject *key1, *key2;
173
174 if (Py_SIZE(set1) != Py_SIZE(set2)) {
175 result = Py_False;
176 } else {
177 result = Py_True;
178
179#if PYTHON_VERSION < 0x300
180 // Same sized set, simply check if values are identical. Other reductions should
181 // make it identical, or else this won't have the effect intended.
182 while (_PySet_Next(set1, &pos1, &key1)) {
183 {
184 NUITKA_MAY_BE_UNUSED int res = _PySet_Next(set2, &pos2, &key2);
185 assert(res != 0);
186 }
187
188 if (key1 != key2) {
189 result = Py_False;
190 break;
191 }
192 }
193#else
194 Py_hash_t unused1, unused2;
195
196 // Same sized dictionary, simply check if values are identical. Other reductions should
197 // make it identical, or else this won't have the effect intended.
198 while (_PySet_NextEntry(set1, &pos1, &key1, &unused1)) {
199 {
200 NUITKA_MAY_BE_UNUSED int res = _PySet_NextEntry(set2, &pos2, &key2, &unused2);
201 assert(res != 0);
202 }
203
204 if (key1 != key2) {
205 result = Py_False;
206 break;
207 }
208 }
209#endif
210 }
211
212 Py_INCREF_IMMORTAL(result);
213 return result;
214}
215
216static PyObject *our_float_tp_richcompare(PyFloatObject *a, PyFloatObject *b, int op) {
217 assert(op == Py_EQ);
218
219 PyObject *result;
220
221 // Avoid the C math when comparing, for it makes too many values equal or unequal.
222 if (memcmp(&a->ob_fval, &b->ob_fval, sizeof(b->ob_fval)) == 0) {
223 result = Py_True;
224 } else {
225 result = Py_False;
226 }
227
228 Py_INCREF_IMMORTAL(result);
229 return result;
230}
231
232static Py_hash_t our_dict_hash(PyObject *dict) {
233 Py_hash_t result = 0;
234
235 Py_ssize_t pos = 0;
236 PyObject *key, *value;
237
238 while (Nuitka_DictNext(dict, &pos, &key, &value)) {
239 result *= 1000003;
240 result ^= Nuitka_FastHashBytes(&key, sizeof(PyObject *));
241 result *= 1000003;
242 result ^= Nuitka_FastHashBytes(&value, sizeof(PyObject *));
243 }
244
245 return result;
246}
247
248static PyObject *our_dict_tp_richcompare(PyObject *a, PyObject *b, int op) {
249 PyObject *result;
250
251 if (Py_SIZE(a) != Py_SIZE(b)) {
252 result = Py_False;
253 } else {
254 result = Py_True;
255
256 Py_ssize_t pos1 = 0, pos2 = 0;
257 PyObject *key1, *value1;
258 PyObject *key2, *value2;
259
260 // Same sized dictionary, simply check if key and values are identical.
261 // Other reductions should make it identical, or else this won't have the
262 // effect intended.
263 while (Nuitka_DictNext(a, &pos1, &key1, &value1)) {
264 {
265 NUITKA_MAY_BE_UNUSED int res = Nuitka_DictNext(b, &pos2, &key2, &value2);
266 assert(res != 0);
267 }
268
269 if (key1 != key2 || value1 != value2) {
270 result = Py_False;
271 break;
272 }
273 }
274 }
275
276 Py_INCREF_IMMORTAL(result);
277 return result;
278}
279
280// For creation of small long singleton long values as required by Python3.
281#if PYTHON_VERSION < 0x3b0
282#if PYTHON_VERSION >= 0x390
283PyObject **Nuitka_Long_SmallValues;
284#elif PYTHON_VERSION >= 0x300
285PyObject *Nuitka_Long_SmallValues[NUITKA_STATIC_SMALLINT_VALUE_MAX - NUITKA_STATIC_SMALLINT_VALUE_MIN + 1];
286#endif
287#endif
288
289static void initCaches(void) {
290 static bool init_done = false;
291 if (init_done == true) {
292 return;
293 }
294
295#if PYTHON_VERSION < 0x300
296 int_cache = PyDict_New();
297#endif
298
299 long_cache = PyDict_New();
300
301 float_cache = PyDict_New();
302
303#if PYTHON_VERSION >= 0x300
304 bytes_cache = PyDict_New();
305#endif
306
307#if PYTHON_VERSION < 0x300
308 unicode_cache = PyDict_New();
309#endif
310
311 tuple_cache = PyDict_New();
312
313 list_cache = PyDict_New();
314
315 dict_cache = PyDict_New();
316
317 set_cache = PyDict_New();
318
319 frozenset_cache = PyDict_New();
320
321#if PYTHON_VERSION < 0x3b0
322#if PYTHON_VERSION >= 0x390
323 // On Python3.9+ these are exposed in the interpreter.
324 Nuitka_Long_SmallValues = (PyObject **)_PyInterpreterState_GET()->small_ints;
325#elif PYTHON_VERSION >= 0x300
326 for (long i = NUITKA_STATIC_SMALLINT_VALUE_MIN; i < NUITKA_STATIC_SMALLINT_VALUE_MAX; i++) {
327 // Have to use the original API here since out "Nuitka_PyLong_FromLong"
328 // would insist on using "Nuitka_Long_SmallValues" to produce it.
329 PyObject *value = PyLong_FromLong(i);
330 Nuitka_Long_SmallValues[NUITKA_TO_SMALL_VALUE_OFFSET(i)] = value;
331 }
332#endif
333#endif
334
335 init_done = true;
336}
337
338static void insertToDictCache(PyObject *dict, PyObject **value) {
339 PyObject *item = PyDict_GetItem(dict, *value);
340
341 if (item != NULL) {
342 *value = item;
343 } else {
344 PyDict_SetItem(dict, *value, *value);
345 }
346}
347
348static void insertToDictCacheForcedHash(PyObject *dict, PyObject **value, hashfunc tp_hash,
349 richcmpfunc tp_richcompare) {
350 hashfunc old_hash = Py_TYPE(*value)->tp_hash;
351 richcmpfunc old_richcmpfunc = Py_TYPE(*value)->tp_richcompare;
352
353 // Hash is optional, e.g. for floats we can spare us doing our own hash,
354 // but we do equality
355 if (tp_hash != NULL) {
356 Py_TYPE(*value)->tp_hash = tp_hash;
357 }
358 Py_TYPE(*value)->tp_richcompare = tp_richcompare;
359
360 insertToDictCache(dict, value);
361
362 Py_TYPE(*value)->tp_hash = old_hash;
363 Py_TYPE(*value)->tp_richcompare = old_richcmpfunc;
364}
365
366static uint16_t unpackValueUint16(unsigned char const **data) {
367 uint16_t value;
368
369 memcpy(&value, *data, sizeof(value));
370
371 assert(sizeof(value) == 2);
372
373 *data += sizeof(value);
374
375 return value;
376}
377
378static uint32_t unpackValueUint32(unsigned char const **data) {
379 uint32_t value;
380
381 memcpy(&value, *data, sizeof(value));
382
383 assert(sizeof(value) == 4);
384
385 *data += sizeof(value);
386
387 return value;
388}
389
390static double unpackValueFloat(unsigned char const **data) {
391 double size;
392
393 memcpy(&size, *data, sizeof(size));
394 *data += sizeof(size);
395
396 return size;
397}
398
399static unsigned char const *_unpackValueCString(unsigned char const *data) {
400 while (*(data++) != 0) {
401 }
402
403 return data;
404}
405
406// Decoding Variable-length quantity values
407static uint64_t _unpackVariableLength(unsigned char const **data) {
408 uint64_t result = 0;
409 uint64_t factor = 1;
410
411 while (1) {
412 unsigned char value = **data;
413 *data += 1;
414
415 result += (value & 127) * factor;
416
417 if (value < 128) {
418 break;
419 }
420
421 factor <<= 7;
422 }
423
424 return result;
425}
426
427static PyObject *_unpackAnonValue(unsigned char anon_index) {
428 switch (anon_index) {
429 case 0:
430 return (PyObject *)Py_TYPE(Py_None);
431 case 1:
432 return (PyObject *)&PyEllipsis_Type;
433 case 2:
434 return (PyObject *)Py_TYPE(Py_NotImplemented);
435 case 3:
436 return (PyObject *)&PyFunction_Type;
437 case 4:
438 return (PyObject *)&PyGen_Type;
439 case 5:
440 return (PyObject *)&PyCFunction_Type;
441 case 6:
442 return (PyObject *)&PyCode_Type;
443 case 7:
444 return (PyObject *)&PyModule_Type;
445
446#if PYTHON_VERSION < 0x300
447 case 8:
448 return (PyObject *)&PyFile_Type;
449 case 9:
450 return (PyObject *)&PyClass_Type;
451 case 10:
452 return (PyObject *)&PyInstance_Type;
453 case 11:
454 return (PyObject *)&PyMethod_Type;
455#endif
456
457#if PYTHON_VERSION >= 0x3a0
458 case 10:
459 return (PyObject *)Nuitka_PyUnion_Type;
460#endif
461
462 default:
463 PRINT_FORMAT("Missing anon value for %d\n", (int)anon_index);
464 NUITKA_CANNOT_GET_HERE("Corrupt constants blob");
465 }
466}
467
468PyObject *_unpackSpecialValue(unsigned char special_index) {
469 switch (special_index) {
470 case 0:
471 return PyObject_GetAttrString((PyObject *)builtin_module, "Ellipsis");
472 case 1:
473 return PyObject_GetAttrString((PyObject *)builtin_module, "NotImplemented");
474 case 2:
475 return Py_SysVersionInfo;
476 default:
477 PRINT_FORMAT("Missing special value for %d\n", (int)special_index);
478 NUITKA_CANNOT_GET_HERE("Corrupt constants blob");
479 }
480}
481
482static PyObject *_Nuitka_Unicode_ImmortalFromStringAndSize(PyThreadState *tstate, const char *data, Py_ssize_t size,
483 bool is_ascii) {
484#if PYTHON_VERSION < 0x300
485 PyObject *u = PyUnicode_FromStringAndSize((const char *)data, size);
486#else
487 // spell-checker: ignore surrogatepass
488 PyObject *u = PyUnicode_DecodeUTF8((const char *)data, size, "surrogatepass");
489#endif
490
491#if PYTHON_VERSION >= 0x3d0 || (PYTHON_VERSION >= 0x3c7 && _NUITKA_EXE_MODE)
492 _PyUnicode_InternImmortal(tstate->interp, &u);
493#elif PYTHON_VERSION >= 0x3c0
494 if (is_ascii) {
495 PyUnicode_InternInPlace(&u);
496 }
497
498#if PYTHON_VERSION >= 0x3c7
499 _PyUnicode_STATE(u).interned = SSTATE_INTERNED_IMMORTAL_STATIC;
500
501#if _NUITKA_EXE_MODE
502 _PyUnicode_STATE(u).statically_allocated = 1;
503#else
504 if (Py_Version >= 0x30c0700) {
505 _PyUnicode_STATE(u).statically_allocated = 1;
506 }
507#endif
508#endif
509
510#elif PYTHON_VERSION >= 0x300
511 if (is_ascii) {
512 PyUnicode_InternInPlace(&u);
513 }
514#else
515 insertToDictCache(unicode_cache, &u);
516#endif
517
518 // Make sure our strings are consistent.
519 // TODO: Check with an assertion making build of Python 3.13.0 if this is really true,
520 // for 3.14 it ought to not be done.
521#if PYTHON_VERSION >= 0x3c0 && PYTHON_VERSION < 0x3e0 && !defined(__NUITKA_NO_ASSERT__)
522 // Note: Setting to immortal happens last, but we want to check now.
523 Py_SET_REFCNT_IMMORTAL(u);
524
525 assert(Nuitka_PyUnicode_CheckConsistency(u, 1));
526#endif
527
528 return u;
529}
530
531static unsigned char const *_unpackBlobConstants(PyThreadState *tstate, PyObject **output, unsigned char const *data,
532 int count);
533
534static unsigned char const *_unpackBlobConstant(PyThreadState *tstate, PyObject **output, unsigned char const *data) {
535
536 // Make sure we discover failures to assign.
537 *output = NULL;
538 bool is_object;
539
540 unsigned char c = *data++;
541#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
542 unsigned char const *data_old = data;
543 printf("Type %u:\n", (unsigned int)c);
544#endif
545 switch (c) {
546
547 case NUITKA_CONSTANT_BLOB_TAG_PREVIOUS: {
548 *output = *(output - 1);
549 is_object = true;
550
551 break;
552 }
553 case NUITKA_CONSTANT_BLOB_TAG_TUPLE: {
554 int size = (int)_unpackVariableLength(&data);
555
556 PyObject *t = PyTuple_New(size);
557 CHECK_OBJECT(t);
558
559 if (size > 0) {
560 data = _unpackBlobConstants(tstate, &PyTuple_GET_ITEM(t, 0), data, size);
561
562 CHECK_OBJECTS(&PyTuple_GET_ITEM(t, 0), size);
563 }
564
565 insertToDictCacheForcedHash(tuple_cache, &t, (hashfunc)our_tuple_hash, (richcmpfunc)our_tuple_tp_richcompare);
566
567 *output = t;
568 is_object = true;
569
570 break;
571 }
572 case NUITKA_CONSTANT_BLOB_TAG_LIST: {
573 int size = (int)_unpackVariableLength(&data);
574
575 PyObject *l = PyList_New(size);
576 CHECK_OBJECT(l);
577
578 if (size > 0) {
579 data = _unpackBlobConstants(tstate, &PyList_GET_ITEM(l, 0), data, size);
580
581 CHECK_OBJECTS(&PyList_GET_ITEM(l, 0), size);
582 }
583
584 insertToDictCacheForcedHash(list_cache, &l, (hashfunc)our_list_hash, (richcmpfunc)our_list_tp_richcompare);
585
586 *output = l;
587 is_object = true;
588
589 break;
590 }
591 case NUITKA_CONSTANT_BLOB_TAG_DICT: {
592 int size = (int)_unpackVariableLength(&data);
593
594 PyObject *d = _PyDict_NewPresized(size);
595 CHECK_OBJECT(d);
596
597 if (size > 0) {
598 NUITKA_DYNAMIC_ARRAY_DECL(keys, PyObject *, size);
599 NUITKA_DYNAMIC_ARRAY_DECL(values, PyObject *, size);
600
601 data = _unpackBlobConstants(tstate, &keys[0], data, size);
602 data = _unpackBlobConstants(tstate, &values[0], data, size);
603
604 CHECK_OBJECTS(&keys[0], size);
605 CHECK_OBJECTS(&values[0], size);
606
607 for (int i = 0; i < size; i++) {
608 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(d, keys[i], values[i]);
609 assert(res == 0);
610 }
611 }
612
613 insertToDictCacheForcedHash(dict_cache, &d, (hashfunc)our_dict_hash, (richcmpfunc)our_dict_tp_richcompare);
614
615 *output = d;
616 is_object = true;
617
618 break;
619 }
620 case NUITKA_CONSTANT_BLOB_TAG_FROZENSET:
621 case NUITKA_CONSTANT_BLOB_TAG_SET: {
622 int size = (int)_unpackVariableLength(&data);
623
624 PyObject *s;
625
626 if (c == NUITKA_CONSTANT_BLOB_TAG_SET) {
627 s = PySet_New(NULL);
628 } else {
629 if (size == 0) {
630 // Get at the frozenset singleton of CPython and use it too. Some things
631 // rely on it being a singleton across the board.
632 static PyObject *empty_frozenset = NULL;
633
634 if (empty_frozenset == NULL) {
635 empty_frozenset = CALL_FUNCTION_WITH_SINGLE_ARG(tstate, (PyObject *)&PyFrozenSet_Type,
636 Nuitka_Bytes_FromStringAndSize("", 0));
637 }
638
639 s = empty_frozenset;
640 } else {
641 s = PyFrozenSet_New(NULL);
642 }
643 }
644
645 CHECK_OBJECT(s);
646
647 if (size > 0) {
648 NUITKA_DYNAMIC_ARRAY_DECL(values, PyObject *, size);
649
650 data = _unpackBlobConstants(tstate, &values[0], data, size);
651
652 CHECK_OBJECTS(&values[0], size);
653
654 for (int i = 0; i < size; i++) {
655 NUITKA_MAY_BE_UNUSED int res = PySet_Add(s, values[i]);
656 assert(res == 0);
657 }
658 }
659
660 // sets are cached globally too.
661 if (c == NUITKA_CONSTANT_BLOB_TAG_SET) {
662 insertToDictCacheForcedHash(set_cache, &s, (hashfunc)our_set_hash, (richcmpfunc)our_set_tp_richcompare);
663 } else {
664 insertToDictCacheForcedHash(frozenset_cache, &s, (hashfunc)our_set_hash,
665 (richcmpfunc)our_set_tp_richcompare);
666 }
667
668 *output = s;
669 is_object = true;
670
671 break;
672 }
673#if PYTHON_VERSION < 0x300
674 case NUITKA_CONSTANT_BLOB_TAG_INT_NEGATIVE:
675 case NUITKA_CONSTANT_BLOB_TAG_INT_POSITIVE: {
676 long value = (long)_unpackVariableLength(&data);
677 if (c == NUITKA_CONSTANT_BLOB_TAG_INT_NEGATIVE) {
678 value = -value;
679 }
680
681 PyObject *i = PyInt_FromLong(value);
682
683 insertToDictCache(int_cache, &i);
684
685 *output = i;
686 is_object = true;
687
688 break;
689 }
690#endif
691 case NUITKA_CONSTANT_BLOB_TAG_LONG_POSITIVE_SMALL:
692 case NUITKA_CONSTANT_BLOB_TAG_LONG_NEGATIVE_SMALL: {
693 // Positive/negative integer value with abs value < 2**31
694 uint64_t value = _unpackVariableLength(&data);
695
696 PyObject *l =
697 Nuitka_LongFromCLong((c == NUITKA_CONSTANT_BLOB_TAG_LONG_POSITIVE_SMALL) ? ((long)value) : (-(long)value));
698 assert(l != NULL);
699
700 // Avoid the long cache, won't do anything useful for small ints
701#if PYTHON_VERSION >= 0x300
702 long check_value = (c == NUITKA_CONSTANT_BLOB_TAG_LONG_POSITIVE_SMALL) ? (long)value : -(long)value;
703 if (check_value < NUITKA_STATIC_SMALLINT_VALUE_MIN || check_value >= NUITKA_STATIC_SMALLINT_VALUE_MAX)
704#endif
705 {
706 insertToDictCache(long_cache, &l);
707 }
708
709 *output = l;
710 is_object = true;
711
712 break;
713 }
714 case NUITKA_CONSTANT_BLOB_TAG_LONG_NEGATIVE_LARGE:
715 case NUITKA_CONSTANT_BLOB_TAG_LONG_POSITIVE_LARGE: {
716 PyObject *result = Nuitka_PyLong_FromLong(0);
717
718 int size = (int)_unpackVariableLength(&data);
719
720 PyObject *shift = Nuitka_PyLong_FromLong(31);
721
722 for (int i = 0; i < size; i++) {
723 result = PyNumber_InPlaceLshift(result, shift);
724
725 uint64_t value = _unpackVariableLength(&data);
726 PyObject *part = Nuitka_LongFromCLong((long)value);
727 assert(part != NULL);
728 result = PyNumber_InPlaceAdd(result, part);
729 Py_DECREF(part);
730 }
731
732 Py_DECREF(shift);
733
734 if (c == NUITKA_CONSTANT_BLOB_TAG_LONG_NEGATIVE_LARGE) {
735 Nuitka_LongSetSignNegative(result);
736 }
737
738 insertToDictCache(long_cache, &result);
739
740 *output = result;
741 is_object = true;
742
743 break;
744 }
745 case NUITKA_CONSTANT_BLOB_TAG_FLOAT: {
746 double value = unpackValueFloat(&data);
747
748 PyObject *f = PyFloat_FromDouble(value);
749
750 // Floats are cached globally too.
751 insertToDictCacheForcedHash(float_cache, &f, NULL, (richcmpfunc)our_float_tp_richcompare);
752
753 *output = f;
754 is_object = true;
755
756 break;
757 }
758 case NUITKA_CONSTANT_BLOB_TAG_COMPLEX: {
759 double real = unpackValueFloat(&data);
760 double imag = unpackValueFloat(&data);
761
762 *output = PyComplex_FromDoubles(real, imag);
763 is_object = true;
764
765 break;
766 }
767 case NUITKA_CONSTANT_BLOB_TAG_COMPLEX_SPECIAL: {
768 PyObject *parts[2];
769
770 // Complex via float is done for ones that are 0, nan, float.
771 data = _unpackBlobConstants(tstate, &parts[0], data, 2);
772
773 *output = BUILTIN_COMPLEX2(tstate, parts[0], parts[1]);
774 is_object = true;
775
776 break;
777 }
778#if PYTHON_VERSION < 0x300
779 case NUITKA_CONSTANT_BLOB_TAG_ATTRIBUTE_NAME:
780 case NUITKA_CONSTANT_BLOB_TAG_BYTES_ZERO_TERMINATED: {
781 // Python2 str, potentially attribute, zero terminated.
782 size_t size = strlen((const char *)data);
783
784 PyObject *s = PyString_FromStringAndSize((const char *)data, size);
785 CHECK_OBJECT(s);
786
787 data += size + 1;
788
789 if (c == NUITKA_CONSTANT_BLOB_TAG_ATTRIBUTE_NAME) {
790 PyString_InternInPlace(&s);
791 }
792
793 *output = s;
794 is_object = true;
795
796 break;
797 }
798#else
799 case NUITKA_CONSTANT_BLOB_TAG_BYTES_ZERO_TERMINATED: {
800 // Python3 bytes, zero terminated.
801 size_t size = strlen((const char *)data);
802
803 PyObject *b = Nuitka_Bytes_FromStringAndSize((const char *)data, size);
804 CHECK_OBJECT(b);
805
806 data += size + 1;
807
808 // Empty bytes value is here as well.
809 if (size > 1) {
810 insertToDictCache(bytes_cache, &b);
811 }
812
813 *output = b;
814 is_object = true;
815
816 break;
817 }
818#endif
819 case NUITKA_CONSTANT_BLOB_TAG_BYTES_SINGLE: {
820 // Python2 str length 1 str, potentially attribute, or Python3 single byte
821
822#if PYTHON_VERSION < 0x300
823 PyObject *s = PyString_FromStringAndSize((const char *)data, 1);
824 data += 1;
825 *output = s;
826#else
827 PyObject *b = Nuitka_Bytes_FromStringAndSize((const char *)data, 1);
828 data += 1;
829 *output = b;
830#endif
831
832 is_object = true;
833
834 break;
835 }
836 case NUITKA_CONSTANT_BLOB_TAG_TEXT_SINGLE: {
837 // Python2 unicode, Python3 str length 1, potentially attribute in Python3
838 PyObject *u = _Nuitka_Unicode_ImmortalFromStringAndSize(tstate, (const char *)data, 1, true);
839 data += 1;
840
841 *output = u;
842 is_object = true;
843
844 break;
845 }
846 case NUITKA_CONSTANT_BLOB_TAG_BYTES_LENGTH_PREFIXED: {
847 // Python2 str or Python3 bytes, length indicated.
848 int size = (int)_unpackVariableLength(&data);
849 assert(size > 1);
850
851 PyObject *b = Nuitka_Bytes_FromStringAndSize((const char *)data, size);
852 CHECK_OBJECT(b);
853
854 data += size;
855
856#if PYTHON_VERSION >= 0x300
857 insertToDictCache(bytes_cache, &b);
858#endif
859
860 *output = b;
861 is_object = true;
862
863 break;
864 }
865
866 case NUITKA_CONSTANT_BLOB_TAG_BYTEARRAY: {
867 int size = (int)_unpackVariableLength(&data);
868
869 PyObject *b = PyByteArray_FromStringAndSize((const char *)data, size);
870 data += size;
871
872 *output = b;
873 is_object = true;
874
875 break;
876 }
877#if PYTHON_VERSION >= 0x300
878 case NUITKA_CONSTANT_BLOB_TAG_ATTRIBUTE_NAME: // Python3 attributes
879#endif
880 case NUITKA_CONSTANT_BLOB_TAG_TEXT_UTF8_ZERO_TERMINATED: { // Python2 unicode, Python3 str, zero terminated.
881 size_t size = strlen((const char *)data);
882 assert(size != 0);
883
884 PyObject *u = _Nuitka_Unicode_ImmortalFromStringAndSize(tstate, (const char *)data, size,
885 c == NUITKA_CONSTANT_BLOB_TAG_ATTRIBUTE_NAME);
886 data += size + 1;
887
888 *output = u;
889 is_object = true;
890
891 break;
892 }
893 case NUITKA_CONSTANT_BLOB_TAG_TEXT_UTF8_LENGTH_PREFIXED: {
894 int size = (int)_unpackVariableLength(&data);
895 assert(size != 0);
896
897 PyObject *u = _Nuitka_Unicode_ImmortalFromStringAndSize(tstate, (const char *)data, size, false);
898 data += size;
899
900 *output = u;
901 is_object = true;
902
903 break;
904 }
905 case NUITKA_CONSTANT_BLOB_TAG_NONE: {
906 *output = Py_None;
907 is_object = true;
908
909 break;
910 }
911 case NUITKA_CONSTANT_BLOB_TAG_TEXT_EMPTY: {
912 *output = _Nuitka_Unicode_ImmortalFromStringAndSize(tstate, (const char *)data, 0, true);
913 is_object = true;
914
915 break;
916 }
917 case NUITKA_CONSTANT_BLOB_TAG_TRUE: {
918 *output = Py_True;
919 is_object = true;
920
921 break;
922 }
923 case NUITKA_CONSTANT_BLOB_TAG_FALSE: {
924 *output = Py_False;
925 is_object = true;
926
927 break;
928 }
929 case NUITKA_CONSTANT_BLOB_TAG_SLICE: {
930 // Slice object
931 PyObject *items[3];
932 data = _unpackBlobConstants(tstate, &items[0], data, 3);
933
934 PyObject *s = MAKE_SLICE_OBJECT3(tstate, items[0], items[1], items[2]);
935
936 *output = s;
937 is_object = true;
938
939 break;
940 }
941 case NUITKA_CONSTANT_BLOB_TAG_RANGE: {
942 // (x)range objects
943 PyObject *items[3];
944 data = _unpackBlobConstants(tstate, &items[0], data, 3);
945#if PYTHON_VERSION < 0x300
946 assert(PyInt_CheckExact(items[0]));
947 assert(PyInt_CheckExact(items[1]));
948 assert(PyInt_CheckExact(items[2]));
949
950 long start = PyInt_AS_LONG(items[0]);
951 long stop = PyInt_AS_LONG(items[1]);
952 long step = PyInt_AS_LONG(items[2]);
953
954 PyObject *s = MAKE_XRANGE(tstate, start, stop, step);
955#else
956 PyObject *s = BUILTIN_XRANGE3(tstate, items[0], items[1], items[2]);
957#endif
958 *output = s;
959 is_object = true;
960
961 break;
962 }
963 case NUITKA_CONSTANT_BLOB_TAG_BUILTIN_ANON: {
964 // Anonymous builtin by table index value.
965 unsigned char anon_index = *data++;
966
967 *output = _unpackAnonValue(anon_index);
968 is_object = true;
969
970 break;
971 }
972 case NUITKA_CONSTANT_BLOB_TAG_BUILTIN_SPECIAL: {
973 // Anonymous builtin by table index value.
974 unsigned char special_index = *data++;
975
976 *output = _unpackSpecialValue(special_index);
977 is_object = true;
978
979 break;
980 }
981 case NUITKA_CONSTANT_BLOB_TAG_BUILTIN_NAMED: {
982 // Builtin by name. TODO: Define number table shared by C and Python
983 // serialization to avoid using strings here.
984 char const *builtin_name = (char const *)data;
985 data = _unpackValueCString(data);
986
987 *output = PyObject_GetAttrString((PyObject *)builtin_module, builtin_name);
988 is_object = true;
989
990 break;
991 }
992 case NUITKA_CONSTANT_BLOB_TAG_BUILTIN_EXCEPTION: {
993 // Builtin exception by name. TODO: Define number table shared by C and Python
994 // serialization to avoid using strings here.
995 char const *builtin_exception_name = (char const *)data;
996 data = _unpackValueCString(data);
997
998 *output = PyObject_GetAttrString((PyObject *)builtin_module, builtin_exception_name);
999 is_object = true;
1000
1001 break;
1002 }
1003 case NUITKA_CONSTANT_BLOB_TAG_FLOAT_SPECIAL: {
1004 unsigned char v = *data++;
1005
1006 PyObject *z = NULL;
1007
1008 switch (v) {
1009 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_POS_ZERO: {
1010 static PyObject *_const_float_0_0 = NULL;
1011
1012 if (_const_float_0_0 == NULL) {
1013 _const_float_0_0 = PyFloat_FromDouble(0.0);
1014 }
1015 z = _const_float_0_0;
1016
1017 break;
1018 }
1019 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_NEG_ZERO: {
1020 static PyObject *_const_float_minus_0_0 = NULL;
1021
1022 if (_const_float_minus_0_0 == NULL) {
1023 _const_float_minus_0_0 = PyFloat_FromDouble(0.0);
1024
1025 // Older Python3 has variable signs from C, so be explicit about it.
1026 PyFloat_SET_DOUBLE(_const_float_minus_0_0, copysign(PyFloat_AS_DOUBLE(_const_float_minus_0_0), -1.0));
1027 }
1028 z = _const_float_minus_0_0;
1029
1030 break;
1031 }
1032
1033 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_POS_NAN: {
1034 static PyObject *_const_float_plus_nan = NULL;
1035
1036 if (_const_float_plus_nan == NULL) {
1037 _const_float_plus_nan = PyFloat_FromDouble(Py_NAN);
1038
1039 // Older Python3 has variable signs for NaN from C, so be explicit about it.
1040 PyFloat_SET_DOUBLE(_const_float_plus_nan, copysign(PyFloat_AS_DOUBLE(_const_float_plus_nan), 1.0));
1041 }
1042 z = _const_float_plus_nan;
1043
1044 break;
1045 }
1046 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_NEG_NAN: {
1047 static PyObject *_const_float_minus_nan = NULL;
1048
1049 if (_const_float_minus_nan == NULL) {
1050 _const_float_minus_nan = PyFloat_FromDouble(Py_NAN);
1051
1052 // Older Python3 has variable signs for NaN from C, so be explicit about it.
1053 PyFloat_SET_DOUBLE(_const_float_minus_nan, copysign(PyFloat_AS_DOUBLE(_const_float_minus_nan), -1.0));
1054 }
1055 z = _const_float_minus_nan;
1056
1057 break;
1058 }
1059 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_POS_INF: {
1060 static PyObject *_const_float_plus_inf = NULL;
1061
1062 if (_const_float_plus_inf == NULL) {
1063 _const_float_plus_inf = PyFloat_FromDouble(Py_HUGE_VAL);
1064
1065 // Older Python3 has variable signs from C, so be explicit about it.
1066 PyFloat_SET_DOUBLE(_const_float_plus_inf, copysign(PyFloat_AS_DOUBLE(_const_float_plus_inf), 1.0));
1067 }
1068 z = _const_float_plus_inf;
1069
1070 break;
1071 }
1072 case NUITKA_CONSTANT_BLOB_FLOAT_SPECIAL_NEG_INF: {
1073 static PyObject *_const_float_minus_inf = NULL;
1074
1075 if (_const_float_minus_inf == NULL) {
1076 _const_float_minus_inf = PyFloat_FromDouble(Py_HUGE_VAL);
1077
1078 // Older Python3 has variable signs from C, so be explicit about it.
1079 PyFloat_SET_DOUBLE(_const_float_minus_inf, copysign(PyFloat_AS_DOUBLE(_const_float_minus_inf), -1.0));
1080 }
1081 z = _const_float_minus_inf;
1082
1083 break;
1084 }
1085 default: {
1086 PRINT_FORMAT("Missing decoding for %d\n", (int)c);
1087 NUITKA_CANNOT_GET_HERE("Corrupt constants blob");
1088 }
1089 }
1090
1091 // Floats are cached globally too.
1092 insertToDictCacheForcedHash(float_cache, &z, NULL, (richcmpfunc)our_float_tp_richcompare);
1093
1094 *output = z;
1095 is_object = true;
1096
1097 break;
1098 }
1099 case NUITKA_CONSTANT_BLOB_TAG_BLOB_DATA: {
1100 // Blob data pointer, user knowns size.
1101 uint64_t size = _unpackVariableLength(&data);
1102
1103 *output = (PyObject *)data;
1104 is_object = false;
1105
1106 data += size;
1107
1108 break;
1109 }
1110#if PYTHON_VERSION >= 0x390
1111 case NUITKA_CONSTANT_BLOB_TAG_GENERIC_ALIAS: {
1112 // GenericAlias object
1113 PyObject *items[2];
1114 data = _unpackBlobConstants(tstate, &items[0], data, 2);
1115
1116 PyObject *g = Py_GenericAlias(items[0], items[1]);
1117
1118 // TODO: Maybe deduplicate.
1119 *output = g;
1120
1121 is_object = true;
1122 break;
1123 }
1124#endif
1125#if PYTHON_VERSION >= 0x3a0
1126 case NUITKA_CONSTANT_BLOB_TAG_UNION_TYPE: {
1127 // UnionType object
1128 PyObject *args;
1129 data = _unpackBlobConstants(tstate, &args, data, 1);
1130
1131 PyObject *union_type = MAKE_UNION_TYPE(args);
1132
1133 // TODO: Maybe deduplicate.
1134 *output = union_type;
1135
1136 is_object = true;
1137 break;
1138 }
1139#endif
1140 case NUITKA_CONSTANT_BLOB_TAG_CODE_OBJECT: {
1141 // Code object, without the filename, we let the module do that,
1142 // depending on the source mode and this is highly compact
1143 // representation of it.
1144
1145 // First, flags with the optional bits. It's handling
1146 // must match that of encoder 100%.
1147 uint64_t flags = _unpackVariableLength(&data);
1148
1149 // Code object flags as used by Python, encoded in the
1150 // flags as well.
1151 int co_flags = 0;
1152
1153 // Name is mandatory, no flag needed.
1154 PyObject *function_name;
1155 data = _unpackBlobConstant(tstate, &function_name, data);
1156
1157 // Line number is mandatory, no flag needed. Encoded values start at 0,
1158 // where 1 is what is normally used.
1159 int line_number = (int)_unpackVariableLength(&data) + 1;
1160
1161 // Right now this is only argument names, so argument count is implied,
1162 // it is mandatory so no flag is needed, empty value is very compact
1163 // anyway and rare.
1164 PyObject *arg_names;
1165 data = _unpackBlobConstant(tstate, &arg_names, data);
1166
1167 // TODO: Not sure if this is redundant potentially it can be derives
1168 // from the var names already. It might be possible to derive by other
1169 // means.
1170 int arg_count = (int)_unpackVariableLength(&data);
1171
1172 // It is version specific if we have this, and dependent on a flag, if
1173 // it's present at all.
1174#if PYTHON_VERSION >= 0x3b0
1175 PyObject *function_qualname;
1176
1177 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_QUALNAME) {
1178 data = _unpackBlobConstant(tstate, &function_qualname, data);
1179 } else {
1180 function_qualname = function_name;
1181 }
1182#endif
1183
1184 // Free vars are optional.
1185 PyObject *free_vars = NULL;
1186
1187 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FREE_VARS) {
1188 data = _unpackBlobConstant(tstate, &free_vars, data);
1189 }
1190
1191#if PYTHON_VERSION >= 0x300
1192 int kw_only_count = 0;
1193 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_KW_ONLY) {
1194 kw_only_count = (int)_unpackVariableLength(&data) + 1;
1195 }
1196 assert(kw_only_count >= 0);
1197#endif
1198
1199#if PYTHON_VERSION >= 0x380
1200 int pos_only_count = 0;
1201 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_POS_ONLY) {
1202 pos_only_count = (int)_unpackVariableLength(&data) + 1;
1203 }
1204 assert(pos_only_count >= 0);
1205#endif
1206
1207 switch (flags & NUITKA_CONSTANT_BLOB_CODE_KIND_MASK) {
1208#if PYTHON_VERSION >= 0x360
1209 case NUITKA_CONSTANT_BLOB_CODE_KIND_ASYNCGEN:
1210 co_flags += CO_ASYNC_GENERATOR;
1211 break;
1212#endif
1213#if PYTHON_VERSION >= 0x350
1214 case NUITKA_CONSTANT_BLOB_CODE_KIND_COROUTINE:
1215 co_flags += CO_COROUTINE;
1216 break;
1217#endif
1218 case NUITKA_CONSTANT_BLOB_CODE_KIND_GENERATOR:
1219 co_flags += CO_GENERATOR;
1220 break;
1221 default:
1222 break;
1223 }
1224
1225 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_OPTIMIZED) {
1226 co_flags += CO_OPTIMIZED;
1227 }
1228
1229 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_NEWLOCALS) {
1230 co_flags += CO_NEWLOCALS;
1231 }
1232
1233 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_VARARGS) {
1234 co_flags += CO_VARARGS;
1235 }
1236
1237 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_VARKEYWORDS) {
1238 co_flags += CO_VARKEYWORDS;
1239 }
1240
1241#if PYTHON_VERSION >= 0x370
1242 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_ANNOTATIONS) {
1243 co_flags += CO_FUTURE_ANNOTATIONS;
1244 }
1245#endif
1246
1247#if PYTHON_VERSION < 0x300
1248 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_DIVISION) {
1249 co_flags += CO_FUTURE_DIVISION;
1250 }
1251#endif
1252
1253 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_UNICODE_LITERALS) {
1254 co_flags += CO_FUTURE_UNICODE_LITERALS;
1255 }
1256
1257#if PYTHON_VERSION < 0x300
1258 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_PRINT_FUNCTION) {
1259 co_flags += CO_FUTURE_PRINT_FUNCTION;
1260 }
1261#endif
1262
1263#if PYTHON_VERSION < 0x300
1264 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_ABSOLUTE_IMPORT) {
1265 co_flags += CO_FUTURE_ABSOLUTE_IMPORT;
1266 }
1267#endif
1268
1269#if PYTHON_VERSION >= 0x350 && PYTHON_VERSION < 0x370
1270 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_GENERATOR_STOP) {
1271 co_flags += CO_FUTURE_GENERATOR_STOP;
1272 }
1273#endif
1274
1275#if PYTHON_VERSION >= 0x300
1276 if (flags & NUITKA_CONSTANT_BLOB_CODE_FLAG_FUTURE_BARRY_AS_BDFL) {
1277 co_flags += CO_FUTURE_BARRY_AS_BDFL;
1278 }
1279#endif
1280
1281 // Filename will be supplied later during usage.
1282 *output = (PyObject *)MAKE_CODE_OBJECT(Py_None, line_number, co_flags, function_name, function_qualname,
1283 arg_names, free_vars, arg_count, kw_only_count, pos_only_count);
1284
1285 CHECK_OBJECT(*output);
1286
1287 is_object = true;
1288 break;
1289 }
1290 case NUITKA_CONSTANT_BLOB_TAG_END: {
1291 PRINT_STRING("Missing blob values\n");
1292 NUITKA_CANNOT_GET_HERE("Corrupt constants blob");
1293 }
1294 default:
1295 PRINT_FORMAT("Missing decoding for %d\n", (int)c);
1296 NUITKA_CANNOT_GET_HERE("Corrupt constants blob");
1297 }
1298
1299#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1300 printf("Size for %u was %d\n", (unsigned int)c, (int)(data - data_old));
1301#endif
1302
1303 // Discourage in-place operations from modifying these. These
1304 // might be put into containers, therefore take 2 refs to be
1305 // accounting for the container too.
1306 if (is_object == true) {
1307 CHECK_OBJECT(*output);
1308
1309#if PYTHON_VERSION < 0x3c0
1310 Py_INCREF(*output);
1311 Py_INCREF(*output);
1312#else
1313 Py_SET_REFCNT_IMMORTAL(*output);
1314#endif
1315 }
1316
1317 return data;
1318}
1319
1320static unsigned char const *_unpackBlobConstants(PyThreadState *tstate, PyObject **output, unsigned char const *data,
1321 int count) {
1322 for (int _i = 0; _i < count; _i++) {
1323 data = _unpackBlobConstant(tstate, output, data);
1324
1325 output += 1;
1326 }
1327
1328 return data;
1329}
1330
1331static int unpackBlobConstants(PyThreadState *tstate, PyObject **output, unsigned char const *data) {
1332 int count = (int)unpackValueUint16(&data);
1333
1334#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1335 printf("unpackBlobConstants count %d\n", count);
1336#endif
1337 _unpackBlobConstants(tstate, output, data, count);
1338
1339 return count;
1340}
1341
1342int loadConstantsBlob(PyThreadState *tstate, PyObject **output, char const *name) {
1343 static bool init_done = false;
1344
1345 if (init_done == false) {
1346 NUITKA_PRINT_TIMING("loadConstantsBlob(): One time init.");
1347
1348#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1349 printf("loadConstantsBlob '%s' one time init\n", name);
1350#endif
1351
1352#if defined(_NUITKA_CONSTANTS_FROM_INCBIN) || defined(_NUITKA_CONSTANTS_FROM_LINKER) || \
1353 defined(_NUITKA_CONSTANTS_FROM_COFF_OBJ) || defined(_NUITKA_CONSTANTS_FROM_CODE) || \
1354 defined(_NUITKA_CONSTANTS_FROM_C23_EMBED) || defined(_NUITKA_CONSTANTS_FROM_RESOURCE) || \
1355 defined(_NUITKA_CONSTANTS_FROM_MACOS_SECTION)
1356 constant_bin = getConstantBlobData();
1357#endif
1358 NUITKA_PRINT_TIMING("loadConstantsBlob(): Found blob, decoding now.");
1359 DECODE(constant_bin);
1360
1361 NUITKA_PRINT_TIMING("loadConstantsBlob(): One time init complete.");
1362
1363 init_done = true;
1364 }
1365
1366#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1367 printf("Loading blob named '%s'\n", name);
1368#endif
1369 // Python 3.9 or higher cannot create dictionary before calling init so avoid it.
1370 if (strcmp(name, ".bytecode") != 0) {
1371 initCaches();
1372 }
1373
1374 unsigned char const *w = constant_bin;
1375
1376 for (;;) {
1377 int match = strcmp(name, (char const *)w);
1378 w += strlen((char const *)w) + 1;
1379
1380#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1381 printf("offset of blob size %d\n", w - constant_bin);
1382#endif
1383
1384 uint32_t size = unpackValueUint32(&w);
1385
1386 if (match == 0) {
1387#ifdef _NUITKA_EXPERIMENTAL_DEBUG_CONSTANTS
1388 printf("Loading blob named '%s' with size %d\n", name, size);
1389#endif
1390 break;
1391 }
1392
1393 // Skip other module data.
1394 w += size;
1395 }
1396
1397 return unpackBlobConstants(tstate, output, w);
1398}
1399
1400// Part of "Nuitka", an optimizing Python compiler that is compatible and
1401// integrates with CPython, but also works on its own.
1402//
1403// Licensed under the GNU Affero General Public License, Version 3 (the "License");
1404// you may not use this file except in compliance with the License.
1405// You may obtain a copy of the License at
1406//
1407// http://www.gnu.org/licenses/agpl.txt
1408//
1409// Unless required by applicable law or agreed to in writing, software
1410// distributed under the License is distributed on an "AS IS" BASIS,
1411// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1412// See the License for the specific language governing permissions and
1413// limitations under the License.