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