Nuitka
The Python compiler
Loading...
Searching...
No Matches
ints.h
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3#ifndef __NUITKA_HELPER_INTS_H__
4#define __NUITKA_HELPER_INTS_H__
5
6// Our "PyLong_FromLong" replacement.
7extern PyObject *Nuitka_PyLong_FromLong(long ival);
8extern long Nuitka_PyLong_AsLongAndOverflow(PyObject *value, int *overflow);
9
10// Our "PyInt_FromLong" replacement, not done (yet?).
11#if PYTHON_VERSION >= 0x300
12#define Nuitka_PyInt_FromLong(ival) Nuitka_PyLong_FromLong(ival)
13#else
14#define Nuitka_PyInt_FromLong(ival) PyInt_FromLong(ival)
15#endif
16
17// We are using this mixed type for both Python2 and Python3, since then we
18// avoid the complexity of overflowed integers for Python2 to switch over.
19
20typedef enum {
21 NUITKA_ILONG_UNASSIGNED = 0,
22 NUITKA_ILONG_OBJECT_VALID = 1,
23 NUITKA_ILONG_CLONG_VALID = 2,
24 NUITKA_ILONG_BOTH_VALID = 3,
25 NUITKA_ILONG_EXCEPTION = 4
26} nuitka_ilong_validity;
27
28typedef struct {
29 nuitka_ilong_validity validity;
30
31 PyObject *python_value;
32 long c_value;
34
35#define IS_NILONG_OBJECT_VALUE_VALID(value) (((value)->validity & NUITKA_ILONG_OBJECT_VALID) != 0)
36#define IS_NILONG_C_VALUE_VALID(value) (((value)->validity & NUITKA_ILONG_CLONG_VALID) != 0)
37
38NUITKA_MAY_BE_UNUSED static void SET_NILONG_OBJECT_VALUE(nuitka_ilong *dual_value, PyObject *python_value) {
39 dual_value->validity = NUITKA_ILONG_OBJECT_VALID;
40 dual_value->python_value = python_value;
41}
42
43NUITKA_MAY_BE_UNUSED static void SET_NILONG_C_VALUE(nuitka_ilong *dual_value, long c_value) {
44 dual_value->validity = NUITKA_ILONG_CLONG_VALID;
45 dual_value->c_value = c_value;
46}
47
48NUITKA_MAY_BE_UNUSED static void SET_NILONG_OBJECT_AND_C_VALUE(nuitka_ilong *dual_value, PyObject *python_value,
49 long c_value) {
50 dual_value->validity = NUITKA_ILONG_BOTH_VALID;
51 dual_value->python_value = python_value;
52 dual_value->c_value = c_value;
53}
54
55NUITKA_MAY_BE_UNUSED static void RELEASE_NILONG_VALUE(nuitka_ilong *dual_value) {
56 if (IS_NILONG_OBJECT_VALUE_VALID(dual_value)) {
57 CHECK_OBJECT(dual_value);
58 Py_DECREF(dual_value->python_value);
59 }
60
61 dual_value->validity = NUITKA_ILONG_UNASSIGNED;
62}
63
64NUITKA_MAY_BE_UNUSED static void INCREF_NILONG_VALUE(nuitka_ilong *dual_value) {
65 if (IS_NILONG_OBJECT_VALUE_VALID(dual_value)) {
66 CHECK_OBJECT(dual_value);
67 Py_INCREF(dual_value->python_value);
68 }
69}
70
71NUITKA_MAY_BE_UNUSED static long GET_NILONG_C_VALUE(nuitka_ilong const *dual_value) {
72 assert(IS_NILONG_C_VALUE_VALID(dual_value));
73 return dual_value->c_value;
74}
75
76NUITKA_MAY_BE_UNUSED static PyObject *GET_NILONG_OBJECT_VALUE(nuitka_ilong const *dual_value) {
77 assert(IS_NILONG_OBJECT_VALUE_VALID(dual_value));
78 return dual_value->python_value;
79}
80
81NUITKA_MAY_BE_UNUSED static void ENFORCE_NILONG_OBJECT_VALUE(nuitka_ilong *dual_value) {
82 assert(dual_value->validity != NUITKA_ILONG_UNASSIGNED);
83
84 if (!IS_NILONG_OBJECT_VALUE_VALID(dual_value)) {
85 dual_value->python_value = Nuitka_PyLong_FromLong(dual_value->c_value);
86
87 dual_value->validity = NUITKA_ILONG_BOTH_VALID;
88 }
89}
90
91NUITKA_MAY_BE_UNUSED static void CHECK_NILONG_OBJECT(nuitka_ilong const *dual_value) {
92 assert(dual_value->validity != NUITKA_ILONG_UNASSIGNED);
93
94 if (IS_NILONG_OBJECT_VALUE_VALID(dual_value)) {
95 CHECK_OBJECT(dual_value);
96 }
97}
98
99NUITKA_MAY_BE_UNUSED static void PRINT_NILONG(nuitka_ilong const *dual_value) {
100 PRINT_FORMAT("NILONG: %d", dual_value->validity);
101 if (IS_NILONG_C_VALUE_VALID(dual_value)) {
102 PRINT_FORMAT("C=%d", dual_value->c_value);
103 }
104 if (IS_NILONG_OBJECT_VALUE_VALID(dual_value)) {
105 PRINT_STRING("Python=");
106 PRINT_ITEM(dual_value->python_value);
107 }
108}
109
110#if PYTHON_VERSION < 0x3c0
111// Convert single digit to sdigit (int32_t),
112// spell-checker: ignore sdigit,stwodigits
113typedef long medium_result_value_t;
114#define MEDIUM_VALUE(x) \
115 (Py_SIZE(x) < 0 ? -(sdigit)((PyLongObject *)(x))->ob_digit[0] \
116 : (Py_SIZE(x) == 0 ? (sdigit)0 : (sdigit)((PyLongObject *)(x))->ob_digit[0]))
117
118#else
119typedef stwodigits medium_result_value_t;
120#define MEDIUM_VALUE(x) ((stwodigits)_PyLong_CompactValue((PyLongObject *)x))
121
122#endif
123
124// TODO: Use this from header files, although they have changed.
125#define NUITKA_STATIC_SMALLINT_VALUE_MIN -5
126#define NUITKA_STATIC_SMALLINT_VALUE_MAX 257
127
128#define NUITKA_TO_SMALL_VALUE_OFFSET(value) (value - NUITKA_STATIC_SMALLINT_VALUE_MIN)
129
130#if PYTHON_VERSION < 0x3b0
131
132#if PYTHON_VERSION >= 0x300
133
134#if PYTHON_VERSION >= 0x390
135extern PyObject **Nuitka_Long_SmallValues;
136#else
137extern PyObject *Nuitka_Long_SmallValues[NUITKA_STATIC_SMALLINT_VALUE_MAX - NUITKA_STATIC_SMALLINT_VALUE_MIN + 1];
138#endif
139
140NUITKA_MAY_BE_UNUSED static inline PyObject *Nuitka_Long_GetSmallValue(int ival) {
141 return Nuitka_Long_SmallValues[NUITKA_TO_SMALL_VALUE_OFFSET(ival)];
142}
143
144#endif
145
146#else
147NUITKA_MAY_BE_UNUSED static inline PyObject *Nuitka_Long_GetSmallValue(medium_result_value_t ival) {
148 return (PyObject *)&_PyLong_SMALL_INTS[NUITKA_TO_SMALL_VALUE_OFFSET(ival)];
149}
150#endif
151
152#endif
153
154// Part of "Nuitka", an optimizing Python compiler that is compatible and
155// integrates with CPython, but also works on its own.
156//
157// Licensed under the GNU Affero General Public License, Version 3 (the "License");
158// you may not use this file except in compliance with the License.
159// You may obtain a copy of the License at
160//
161// http://www.gnu.org/licenses/agpl.txt
162//
163// Unless required by applicable law or agreed to in writing, software
164// distributed under the License is distributed on an "AS IS" BASIS,
165// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
166// See the License for the specific language governing permissions and
167// limitations under the License.
Definition ints.h:28