Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationBinaryAddUtils.c
1// Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* These slots are still manually coded and are used by the generated code.
4 *
5 * The plan should be to generate these as well, so e.g. we can have a slot
6 * SLOT_nb_add_LONG_INT that is optimal too.
7 */
8
9// This file is included from another C file, help IDEs to still parse it on
10// its own.
11#ifdef __IDE_ONLY__
12#include "nuitka/prelude.h"
13#endif
14
15static PyObject *LIST_CONCAT(PyThreadState *tstate, PyObject *operand1, PyObject *operand2) {
16 CHECK_OBJECT(operand1);
17 assert(PyList_CheckExact(operand1));
18 CHECK_OBJECT(operand2);
19 assert(PyList_CheckExact(operand2));
20
21 Py_ssize_t size = Py_SIZE(operand1) + Py_SIZE(operand2);
22
23 PyListObject *result = (PyListObject *)MAKE_LIST_EMPTY(tstate, size);
24 if (unlikely(result == NULL)) {
25 return NULL;
26 }
27
28 PyObject **src = ((PyListObject *)operand1)->ob_item;
29 PyObject **dest = result->ob_item;
30
31 for (Py_ssize_t i = 0; i < Py_SIZE(operand1); i++) {
32 PyObject *v = src[i];
33 Py_INCREF(v);
34 dest[i] = v;
35 }
36 src = ((PyListObject *)operand2)->ob_item;
37 dest = result->ob_item + Py_SIZE(operand1);
38 for (Py_ssize_t i = 0; i < Py_SIZE(operand2); i++) {
39 PyObject *v = src[i];
40 Py_INCREF(v);
41 dest[i] = v;
42 }
43 return (PyObject *)result;
44}
45
46// Needed for offsetof, LONG_MIN and LONG_MAX.
47#include <limits.h>
48#include <stddef.h>
49
50#if PYTHON_VERSION < 0x3c0
51#define MAX_LONG_DIGITS ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit)) / sizeof(digit))
52#define Nuitka_LongGetDigitPointer(value) (&(((PyLongObject *)value)->ob_digit[0]))
53#define Nuitka_LongGetDigitSize(value) (Py_ABS(Py_SIZE(value)))
54#define Nuitka_LongGetSignedDigitSize(value) (Py_SIZE(value))
55#define Nuitka_LongIsNegative(value) (Py_SIZE(value) < 0)
56#define Nuitka_LongSetSignNegative(value) Py_SET_SIZE(value, -Py_ABS(Py_SIZE(value)))
57#define Nuitka_LongSetSign(value, positive) Py_SET_SIZE(value, (((positive) ? 1 : -1) * Py_ABS(Py_SIZE(value))))
58#define Nuitka_LongFlipSign(value) Py_SET_SIZE(value, -Py_SIZE(value))
59#define Nuitka_LongSetDigitSizeAndNegative(value, count, negative) Py_SET_SIZE(value, negative ? -count : count)
60#else
61#define MAX_LONG_DIGITS ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit)) / sizeof(digit))
62
63#define Nuitka_LongGetDigitPointer(value) (&(((PyLongObject *)value)->long_value.ob_digit[0]))
64#define Nuitka_LongGetDigitSize(value) (_PyLong_DigitCount((PyLongObject const *)(value)))
65#define Nuitka_LongGetSignedDigitSize(value) (_PyLong_SignedDigitCount((PyLongObject const *)(value)))
66#define Nuitka_LongIsNegative(value) (((PyLongObject *)value)->long_value.lv_tag & SIGN_NEGATIVE)
67#define Nuitka_LongSetSignNegative(value) \
68 ((PyLongObject *)value)->long_value.lv_tag = ((PyLongObject *)value)->long_value.lv_tag | SIGN_NEGATIVE;
69#define Nuitka_LongSetSignPositive(value) \
70 ((PyLongObject *)value)->long_value.lv_tag = ((PyLongObject *)value)->long_value.lv_tag & ~(SIGN_NEGATIVE);
71#define Nuitka_LongSetSign(value, positive) \
72 if (positive) { \
73 Nuitka_LongSetSignPositive(value); \
74 } else { \
75 Nuitka_LongSetSignNegative(value); \
76 }
77#define Nuitka_LongSetDigitSizeAndNegative(value, count, negative) \
78 _PyLong_SetSignAndDigitCount(value, negative ? -1 : 1, count)
79#define Nuitka_LongFlipSign(value) _PyLong_FlipSign(value)
80#endif
81
82// Our version of _PyLong_New(size);
83static PyLongObject *Nuitka_LongNew(Py_ssize_t size) {
84 // TODO: The assertion may be a bit to strong, could be <= for at least < 3.12
85 assert(size < (Py_ssize_t)MAX_LONG_DIGITS);
86 assert(size >= 0);
87
88#if PYTHON_VERSION >= 0x3c0
89 // The zero now is a single digit number.
90 Py_ssize_t ndigits = size ? size : 1;
91
92 PyLongObject *result =
93 (PyLongObject *)NuitkaObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) + ndigits * sizeof(digit));
94 _PyLong_SetSignAndDigitCount(result, size != 0, size);
95 PyObject_INIT(result, &PyLong_Type);
96 result->long_value.ob_digit[0] = 0;
97 return result;
98#elif PYTHON_VERSION >= 0x300
99 PyLongObject *result = (PyLongObject *)NuitkaObject_Malloc(offsetof(PyLongObject, ob_digit) + size * sizeof(digit));
100 return (PyLongObject *)PyObject_INIT_VAR(result, &PyLong_Type, size);
101#else
102 return (PyLongObject *)PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
103#endif
104}
105
106static PyObject *Nuitka_LongRealloc(PyObject *value, Py_ssize_t size) {
107 assert(size >= 0);
108
109 PyLongObject *result = Nuitka_LongNew(size);
110 Nuitka_LongSetDigitSizeAndNegative(result, size, false);
111 Py_DECREF(value);
112
113 return (PyObject *)result;
114}
115
116static PyObject *Nuitka_LongFromCLong(long ival) {
117#if PYTHON_VERSION < 0x300
118 if (ival == 0) {
119 PyLongObject *result = Nuitka_LongNew(0);
120
121 return (PyObject *)result;
122 }
123#else
124 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
125 PyObject *result = Nuitka_Long_GetSmallValue(ival);
126 Py_INCREF(result);
127
128 return result;
129 }
130#endif
131
132 // We go via unsigned long to avoid overflows when shifting and we need
133 // the sign separate in the end anyway.
134 unsigned long abs_ival;
135 bool negative;
136
137 if (ival < 0) {
138 abs_ival = 0U - (unsigned long)ival;
139 negative = true;
140 } else {
141 abs_ival = (unsigned long)ival;
142 negative = false;
143 }
144
145 // Fast path for single digit values
146 if (!(abs_ival >> PyLong_SHIFT)) {
147 PyLongObject *result = Nuitka_LongNew(1);
148 assert(result != NULL);
149 if (negative) {
150 Nuitka_LongSetSignNegative(result);
151 }
152
153 digit *digits = Nuitka_LongGetDigitPointer(result);
154 digits[0] = (digit)abs_ival;
155
156 return (PyObject *)result;
157 }
158
159 // Fast path for two digit values on suitable platforms.
160#if PyLong_SHIFT == 15
161 if (!(abs_ival >> 2 * PyLong_SHIFT)) {
162 PyLongObject *result = Nuitka_LongNew(2);
163 assert(result != NULL);
164 if (negative) {
165 Nuitka_LongSetSignNegative(result);
166 }
167
168 digit *digits = Nuitka_LongGetDigitPointer(result);
169
170 digits[0] = (digit)(abs_ival & PyLong_MASK);
171 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
172
173 return (PyObject *)result;
174 }
175#endif
176
177 // Slow path for the rest.
178 unsigned long t = abs_ival;
179 Py_ssize_t ndigits = 0;
180
181 // First determine the number of digits needed.
182 while (t != 0) {
183 ++ndigits;
184 t >>= PyLong_SHIFT;
185 }
186
187 PyLongObject *result = _PyLong_New(ndigits);
188 assert(result != NULL);
189
190 Nuitka_LongSetDigitSizeAndNegative(result, ndigits, negative);
191
192 digit *d = Nuitka_LongGetDigitPointer(result);
193
194 // Now copy the digits
195 t = abs_ival;
196 while (t != 0) {
197 *d++ = (digit)(t & PyLong_MASK);
198 t >>= PyLong_SHIFT;
199 }
200
201 return (PyObject *)result;
202}
203
204// Our "PyLong_FromLong" replacement.
205PyObject *Nuitka_PyLong_FromLong(long ival) { return Nuitka_LongFromCLong(ival); }
206
207// Our "PyLong_AsLongAndOverflow" replacement with a fast path for exact long values.
208long Nuitka_PyLong_AsLongAndOverflow(PyObject *value, int *overflow) {
209 CHECK_OBJECT(value);
210 assert(overflow != NULL);
211
212 *overflow = 0;
213
214 if (value == Py_False) {
215 return 0;
216 }
217
218 if (value == Py_True) {
219 return 1;
220 }
221
222#if PYTHON_VERSION < 0x300
223 if (PyInt_CheckExact(value)) {
224 return PyInt_AS_LONG(value);
225 }
226#endif
227
228 if (PyLong_CheckExact(value)) {
229 Py_ssize_t digit_count = Nuitka_LongGetDigitSize(value);
230
231 if (digit_count == 0) {
232 return 0;
233 }
234
235 if (digit_count == 1) {
236 return (long)MEDIUM_VALUE(value);
237 }
238
239 digit const *digits = Nuitka_LongGetDigitPointer(value);
240 unsigned long result = 0;
241 bool negative = Nuitka_LongIsNegative(value);
242
243 for (Py_ssize_t i = digit_count; i > 0; i--) {
244 if (result > (ULONG_MAX >> PyLong_SHIFT)) {
245 *overflow = negative ? -1 : 1;
246 return -1;
247 }
248
249 result <<= PyLong_SHIFT;
250
251 if (result > ULONG_MAX - digits[i - 1]) {
252 *overflow = negative ? -1 : 1;
253 return -1;
254 }
255
256 result += digits[i - 1];
257 }
258
259 if (negative) {
260 unsigned long const negative_limit = (unsigned long)LONG_MAX + 1UL;
261
262 if (result > negative_limit) {
263 *overflow = -1;
264 return -1;
265 }
266
267 if (result == negative_limit) {
268 return LONG_MIN;
269 }
270
271 return -(long)result;
272 }
273
274 if (result > (unsigned long)LONG_MAX) {
275 *overflow = 1;
276 return -1;
277 }
278
279 return (long)result;
280 }
281
282#if PYTHON_VERSION >= 0x270
283 return PyLong_AsLongAndOverflow(value, overflow);
284#else
285 // TODO: Python 2.6 doesn't have the overflow-reporting API, but we will add
286 // our own PyLong_AsLongAndOverflow anyway.
287 return PyLong_AsLong(value);
288#endif
289}
290
291static void Nuitka_LongUpdateFromCLong(PyObject **value, long ival) {
292 assert(Py_REFCNT(*value) == 1);
293
294#if PYTHON_VERSION < 0x300
295 if (ival == 0) {
296 if (Py_SIZE(*value) == 0) {
297 return;
298 }
299
300 Py_DECREF(*value);
301 *value = (PyObject *)Nuitka_LongNew(0);
302
303 return;
304 }
305#else
306 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
307 Py_DECREF(*value);
308
309 *value = Nuitka_Long_GetSmallValue(ival);
310 Py_INCREF(*value);
311
312 return;
313 }
314#endif
315
316 // We go via unsigned long to avoid overflows when shifting and we need
317 // the sign separate in the end anyway.
318 unsigned long abs_ival;
319 bool negative;
320
321 if (ival < 0) {
322 abs_ival = 0U - (unsigned long)ival;
323 negative = true;
324 } else {
325 abs_ival = (unsigned long)ival;
326 negative = false;
327 }
328
329 // Fast path for single digit values
330 if (!(abs_ival >> PyLong_SHIFT)) {
331 PyLongObject *result;
332
333#if PYTHON_VERSION < 0x3c0
334 if (unlikely(Py_SIZE(*value) == 0)) {
335 *value = Nuitka_LongRealloc(*value, 1);
336 CHECK_OBJECT(*value);
337
338 result = (PyLongObject *)*value;
339 } else
340#endif
341 {
342 result = (PyLongObject *)(*value);
343 }
344
345 Nuitka_LongSetSign(result, !negative);
346
347 digit *digits = Nuitka_LongGetDigitPointer(result);
348 digits[0] = (digit)abs_ival;
349
350 return;
351 }
352
353 // Fast path for two digit values on suitable platforms, e.g. armv7l
354#if PyLong_SHIFT == 15
355 if (!(abs_ival >> 2 * PyLong_SHIFT)) {
356 PyLongObject *result;
357 if (unlikely(Py_ABS(Py_SIZE(*value)) < 2)) {
358 *value = Nuitka_LongRealloc(*value, 2);
359 CHECK_OBJECT(*value);
360
361 result = (PyLongObject *)*value;
362 } else {
363 result = (PyLongObject *)(*value);
364 }
365
366 if (negative) {
367 Nuitka_LongSetSignNegative(result);
368 }
369
370 digit *digits = Nuitka_LongGetDigitPointer(result);
371
372 digits[0] = (digit)(abs_ival & PyLong_MASK);
373 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
374
375 return;
376 }
377#endif
378
379 // Slow path for the rest.
380 unsigned long t = abs_ival;
381 Py_ssize_t ndigits = 0;
382
383 // First determine the number of digits needed.
384 while (t != 0) {
385 ndigits++;
386 t >>= PyLong_SHIFT;
387 }
388
389 if (unlikely(Py_ABS(Py_SIZE(*value)) < ndigits)) {
390 *value = Nuitka_LongRealloc(*value, ndigits);
391 }
392
393 CHECK_OBJECT(*value);
394
395 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)*value, ndigits, negative);
396
397 digit *d = Nuitka_LongGetDigitPointer(*value);
398
399 // Now copy the digits
400 t = abs_ival;
401 while (t) {
402 *d++ = (digit)(t & PyLong_MASK);
403 t >>= PyLong_SHIFT;
404 }
405
406 return;
407}
408
409#if 0
410// Note: We are manually inlining this so far.
411static PyLongObject *Nuitka_LongStripZeros(PyLongObject *v) {
412 Py_ssize_t j = Py_ABS(Py_SIZE(v));
413
414 Py_ssize_t i = j;
415 while (i > 0 && v->ob_digit[i - 1] == 0) {
416 i -= 1;
417 }
418
419 if (i != j) {
420 Py_SIZE(v) = (Py_SIZE(v) < 0) ? -i : i;
421 }
422
423 return v;
424}
425#endif
426
427static PyLongObject *_Nuitka_LongAddDigits(digit const *a, Py_ssize_t size_a, digit const *b, Py_ssize_t size_b) {
428 // Make sure we know a is the longest value.
429 if (size_a < size_b) {
430 {
431 digit const *temp = a;
432 a = b;
433 b = temp;
434 }
435
436 {
437 Py_ssize_t temp = size_a;
438 size_a = size_b;
439 size_b = temp;
440 }
441 }
442
443 // We do not know ahead of time, if we need a new digit, lets just allocate it.
444 PyLongObject *result = Nuitka_LongNew(size_a + 1);
445 CHECK_OBJECT(result);
446
447 digit *r = Nuitka_LongGetDigitPointer(result);
448
449 digit carry = 0;
450
451 // First common digits.
452 Py_ssize_t i;
453 for (i = 0; i < size_b; i++) {
454 carry += a[i] + b[i];
455 r[i] = carry & PyLong_MASK;
456 carry >>= PyLong_SHIFT;
457 }
458 // Digits from longest one only.
459 for (; i < size_a; i++) {
460 carry += a[i];
461 r[i] = carry & PyLong_MASK;
462 carry >>= PyLong_SHIFT;
463 }
464
465 // Only the top digit can be zero, so we can strip this faster.
466 if (carry) {
467 r[i] = carry;
468 } else {
469 // Note: Beware, this looses the sign value.
470 Nuitka_LongSetDigitSizeAndNegative(result, Nuitka_LongGetDigitSize(result) - 1, false);
471 }
472
473 return result;
474}
475
476static PyObject *_Nuitka_LongAddInplaceDigits(PyObject *left, digit const *b, Py_ssize_t size_b) {
477 digit const *a = Nuitka_LongGetDigitPointer(left);
478 Py_ssize_t size_a = Nuitka_LongGetDigitSize(left);
479
480 digit const *aa = a;
481 digit const *bb = b;
482
483 // Make sure we know aa is the longest value by swapping a/b attributes.
484 if (size_a < size_b) {
485 {
486 aa = b;
487 bb = a;
488 }
489
490 {
491 Py_ssize_t temp = size_a;
492 size_a = size_b;
493 size_b = temp;
494 }
495 }
496
497 digit carry = 0;
498
499 // First common digits.
500 Py_ssize_t i;
501 for (i = 0; i < size_b; i++) {
502 carry += aa[i] + bb[i];
503 carry >>= PyLong_SHIFT;
504 }
505
506 // Digits from longest one only might cause a new digit through carry.
507 Py_ssize_t needed = size_a;
508
509 for (; i < size_a; i++) {
510 carry += aa[i];
511 carry >>= PyLong_SHIFT;
512
513 // No more carry, that means size cannot increase.
514 if (carry == 0) {
515 break;
516 }
517 }
518
519 // Final digit needs to be added.
520 if (carry) {
521 needed = i + 1;
522 }
523
524 // Need to keep the old value around, or else we commit use after free potentially.
525 PyObject *old = left;
526
527 if (needed > Nuitka_LongGetDigitSize(left)) {
528 left = (PyObject *)Nuitka_LongNew(needed);
529 } else {
530 Py_INCREF(old);
531 }
532
533 digit *r = Nuitka_LongGetDigitPointer(left);
534
535 // Now do the real thing, with actual storage to left digits.
536 carry = 0;
537
538 // First common digits.
539 for (i = 0; i < size_b; i++) {
540 carry += aa[i] + bb[i];
541 r[i] = carry & PyLong_MASK;
542 carry >>= PyLong_SHIFT;
543 }
544 // Digits from longest one only.
545 for (; i < size_a; i++) {
546 carry += aa[i];
547 r[i] = carry & PyLong_MASK;
548 carry >>= PyLong_SHIFT;
549 }
550
551 // Final digit from the carry.
552 if (carry != 0) {
553 r[i] = carry;
554
555 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i + 1, false);
556 } else {
557 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i, false);
558 }
559
560 // Release reference to old value
561 Py_DECREF(old);
562
563 return left;
564}
565
566static PyLongObject *_Nuitka_LongSubDigits(digit const *a, Py_ssize_t size_a, digit const *b, Py_ssize_t size_b) {
567 // Sign of the result.
568 int sign = 1;
569
570 // Make sure we know a is the largest value.
571 if (size_a < size_b) {
572 sign = -1;
573
574 {
575 digit const *temp = a;
576 a = b;
577 b = temp;
578 }
579
580 {
581 Py_ssize_t temp = size_a;
582 size_a = size_b;
583 size_b = temp;
584 }
585 } else if (size_a == size_b) {
586 // Find highest digit where a and b differ:
587 Py_ssize_t i = size_a;
588 while (--i >= 0 && a[i] == b[i]) {
589 }
590
591 if (i < 0) {
592#if PYTHON_VERSION < 0x300
593 return (PyLongObject *)Nuitka_LongFromCLong(0);
594#else
595 // For Python3, we have this prepared.
596 PyObject *result = Nuitka_Long_GetSmallValue(0);
597 Py_INCREF(result);
598 return (PyLongObject *)result;
599#endif
600 }
601
602 if (a[i] < b[i]) {
603 sign = -1;
604
605 {
606 digit const *temp = a;
607 a = b;
608 b = temp;
609 }
610 }
611
612 size_a = size_b = i + 1;
613 }
614
615 PyLongObject *result = Nuitka_LongNew(size_a);
616 CHECK_OBJECT(result);
617
618 digit *r = Nuitka_LongGetDigitPointer(result);
619
620 digit borrow = 0;
621
622 Py_ssize_t i;
623 // First common digits.
624 for (i = 0; i < size_b; i++) {
625 borrow = a[i] - b[i] - borrow;
626 r[i] = borrow & PyLong_MASK;
627 borrow >>= PyLong_SHIFT;
628 borrow &= 1;
629 }
630 // Digits from largest one only.
631 for (; i < size_a; i++) {
632 borrow = a[i] - borrow;
633 r[i] = borrow & PyLong_MASK;
634 borrow >>= PyLong_SHIFT;
635 borrow &= 1;
636 }
637 assert(borrow == 0);
638
639 // Strip leading zeros.
640 while (i > 0 && r[i - 1] == 0) {
641 i -= 1;
642 }
643
644 Nuitka_LongSetDigitSizeAndNegative(result, i, sign < 0);
645
646#if PYTHON_VERSION >= 0x300
647 // Normalize small integers.
648 if (i <= 1) {
649 medium_result_value_t ival = MEDIUM_VALUE(result);
650
651 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
652 Py_DECREF(result);
653
654 result = (PyLongObject *)Nuitka_Long_GetSmallValue(ival);
655 Py_INCREF(result);
656 }
657 }
658#endif
659
660 return result;
661}
662
663static PyObject *_Nuitka_LongSubInplaceDigits(PyObject *left, digit const *b, Py_ssize_t size_b, int sign) {
664 digit const *a = Nuitka_LongGetDigitPointer(left);
665 Py_ssize_t size_a = Nuitka_LongGetDigitSize(left);
666
667 digit const *aa = a;
668 digit const *bb = b;
669
670 // Make sure we know a is the largest value.
671 if (size_a < size_b) {
672 // Invert the sign of the result by swapping the order.
673 sign *= -1;
674
675 {
676 aa = b;
677 bb = a;
678 }
679
680 {
681 Py_ssize_t temp = size_a;
682 size_a = size_b;
683 size_b = temp;
684 }
685 } else if (size_a == size_b) {
686 // Find highest digit where a and b differ:
687 Py_ssize_t i = size_a;
688 while (--i >= 0 && a[i] == b[i]) {
689 }
690
691 // TODO: This will benefit a lot by being in a template.
692 if (i < 0) {
693#if PYTHON_VERSION < 0x300
694 PyObject *r = const_long_0;
695#else
696 PyObject *r = Nuitka_Long_GetSmallValue(0);
697#endif
698 Py_INCREF(r);
699 Py_DECREF(left);
700
701 return r;
702 }
703
704 if (aa[i] < bb[i]) {
705 sign *= -1;
706
707 {
708 aa = b;
709 bb = a;
710 }
711 }
712
713 size_a = size_b = i + 1;
714 }
715
716 Py_ssize_t needed = size_a;
717
718 // Need to keep the old value around, or else we commit use after free potentially.
719 PyObject *old = left;
720
721 if (needed > Nuitka_LongGetDigitSize(left)) {
722 left = (PyObject *)Nuitka_LongNew(needed);
723 } else {
724 Py_INCREF(old);
725 }
726
727 digit *r = Nuitka_LongGetDigitPointer(left);
728
729 digit borrow = 0;
730
731 Py_ssize_t i;
732 // First common digits.
733 for (i = 0; i < size_b; i++) {
734 borrow = aa[i] - bb[i] - borrow;
735 r[i] = borrow & PyLong_MASK;
736 borrow >>= PyLong_SHIFT;
737 borrow &= 1;
738 }
739 // Digits from largest one only.
740 for (; i < size_a; i++) {
741 borrow = aa[i] - borrow;
742 r[i] = borrow & PyLong_MASK;
743 borrow >>= PyLong_SHIFT;
744 borrow &= 1;
745 }
746 assert(borrow == 0);
747
748 // Strip leading zeros.
749 while (i > 0 && r[i - 1] == 0) {
750 i -= 1;
751 }
752
753 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i, (sign < 0));
754
755 // Release reference to old value
756 Py_DECREF(old);
757
758#if PYTHON_VERSION >= 0x300
759 // Normalize small integers.
760 if (i <= 1) {
761 medium_result_value_t ival = MEDIUM_VALUE(left);
762
763 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
764 Py_DECREF(left);
765
766 left = Nuitka_Long_GetSmallValue(ival);
767 Py_INCREF(left);
768 }
769 }
770#endif
771
772 return left;
773}
774
775// Part of "Nuitka", an optimizing Python compiler that is compatible and
776// integrates with CPython, but also works on its own.
777//
778// Licensed under the GNU Affero General Public License, Version 3 (the "License");
779// you may not use this file except in compliance with the License.
780// You may obtain a copy of the License at
781//
782// http://www.gnu.org/licenses/agpl.txt
783//
784// Unless required by applicable law or agreed to in writing, software
785// distributed under the License is distributed on an "AS IS" BASIS,
786// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
787// See the License for the specific language governing permissions and
788// limitations under the License.