12#include "nuitka/prelude.h"
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));
21 Py_ssize_t size = Py_SIZE(operand1) + Py_SIZE(operand2);
23 PyListObject *result = (PyListObject *)MAKE_LIST_EMPTY(tstate, size);
24 if (unlikely(result == NULL)) {
28 PyObject **src = ((PyListObject *)operand1)->ob_item;
29 PyObject **dest = result->ob_item;
31 for (Py_ssize_t i = 0; i < Py_SIZE(operand1); i++) {
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++) {
43 return (PyObject *)result;
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)
61#define MAX_LONG_DIGITS ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit)) / sizeof(digit))
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) \
73 Nuitka_LongSetSignPositive(value); \
75 Nuitka_LongSetSignNegative(value); \
77#define Nuitka_LongSetDigitSizeAndNegative(value, count, negative) \
78 _PyLong_SetSignAndDigitCount(value, negative ? -1 : 1, count)
79#define Nuitka_LongFlipSign(value) _PyLong_FlipSign(value)
83static PyLongObject *Nuitka_LongNew(Py_ssize_t size) {
85 assert(size < (Py_ssize_t)MAX_LONG_DIGITS);
88#if PYTHON_VERSION >= 0x3c0
90 Py_ssize_t ndigits = size ? size : 1;
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;
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);
102 return (PyLongObject *)PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
106static PyObject *Nuitka_LongRealloc(PyObject *value, Py_ssize_t size) {
109 PyLongObject *result = Nuitka_LongNew(size);
110 Nuitka_LongSetDigitSizeAndNegative(result, size,
false);
113 return (PyObject *)result;
116static PyObject *Nuitka_LongFromCLong(
long ival) {
117#if PYTHON_VERSION < 0x300
119 PyLongObject *result = Nuitka_LongNew(0);
121 return (PyObject *)result;
124 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
125 PyObject *result = Nuitka_Long_GetSmallValue(ival);
134 unsigned long abs_ival;
138 abs_ival = 0U - (
unsigned long)ival;
141 abs_ival = (
unsigned long)ival;
146 if (!(abs_ival >> PyLong_SHIFT)) {
147 PyLongObject *result = Nuitka_LongNew(1);
148 assert(result != NULL);
150 Nuitka_LongSetSignNegative(result);
153 digit *digits = Nuitka_LongGetDigitPointer(result);
154 digits[0] = (digit)abs_ival;
156 return (PyObject *)result;
160#if PyLong_SHIFT == 15
161 if (!(abs_ival >> 2 * PyLong_SHIFT)) {
162 PyLongObject *result = Nuitka_LongNew(2);
163 assert(result != NULL);
165 Nuitka_LongSetSignNegative(result);
168 digit *digits = Nuitka_LongGetDigitPointer(result);
170 digits[0] = (digit)(abs_ival & PyLong_MASK);
171 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
173 return (PyObject *)result;
178 unsigned long t = abs_ival;
179 Py_ssize_t ndigits = 0;
187 PyLongObject *result = _PyLong_New(ndigits);
188 assert(result != NULL);
190 Nuitka_LongSetDigitSizeAndNegative(result, ndigits, negative);
192 digit *d = Nuitka_LongGetDigitPointer(result);
197 *d++ = (digit)(t & PyLong_MASK);
201 return (PyObject *)result;
205PyObject *Nuitka_PyLong_FromLong(
long ival) {
return Nuitka_LongFromCLong(ival); }
208long Nuitka_PyLong_AsLongAndOverflow(PyObject *value,
int *overflow) {
210 assert(overflow != NULL);
214 if (value == Py_False) {
218 if (value == Py_True) {
222#if PYTHON_VERSION < 0x300
223 if (PyInt_CheckExact(value)) {
224 return PyInt_AS_LONG(value);
228 if (PyLong_CheckExact(value)) {
229 Py_ssize_t digit_count = Nuitka_LongGetDigitSize(value);
231 if (digit_count == 0) {
235 if (digit_count == 1) {
236 return (
long)MEDIUM_VALUE(value);
239 digit
const *digits = Nuitka_LongGetDigitPointer(value);
240 unsigned long result = 0;
241 bool negative = Nuitka_LongIsNegative(value);
243 for (Py_ssize_t i = digit_count; i > 0; i--) {
244 if (result > (ULONG_MAX >> PyLong_SHIFT)) {
245 *overflow = negative ? -1 : 1;
249 result <<= PyLong_SHIFT;
251 if (result > ULONG_MAX - digits[i - 1]) {
252 *overflow = negative ? -1 : 1;
256 result += digits[i - 1];
260 unsigned long const negative_limit = (
unsigned long)LONG_MAX + 1UL;
262 if (result > negative_limit) {
267 if (result == negative_limit) {
271 return -(long)result;
274 if (result > (
unsigned long)LONG_MAX) {
282#if PYTHON_VERSION >= 0x270
283 return PyLong_AsLongAndOverflow(value, overflow);
287 return PyLong_AsLong(value);
291static void Nuitka_LongUpdateFromCLong(PyObject **value,
long ival) {
292 assert(Py_REFCNT(*value) == 1);
294#if PYTHON_VERSION < 0x300
296 if (Py_SIZE(*value) == 0) {
301 *value = (PyObject *)Nuitka_LongNew(0);
306 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
309 *value = Nuitka_Long_GetSmallValue(ival);
318 unsigned long abs_ival;
322 abs_ival = 0U - (
unsigned long)ival;
325 abs_ival = (
unsigned long)ival;
330 if (!(abs_ival >> PyLong_SHIFT)) {
331 PyLongObject *result;
333#if PYTHON_VERSION < 0x3c0
334 if (unlikely(Py_SIZE(*value) == 0)) {
335 *value = Nuitka_LongRealloc(*value, 1);
336 CHECK_OBJECT(*value);
338 result = (PyLongObject *)*value;
342 result = (PyLongObject *)(*value);
345 Nuitka_LongSetSign(result, !negative);
347 digit *digits = Nuitka_LongGetDigitPointer(result);
348 digits[0] = (digit)abs_ival;
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);
361 result = (PyLongObject *)*value;
363 result = (PyLongObject *)(*value);
367 Nuitka_LongSetSignNegative(result);
370 digit *digits = Nuitka_LongGetDigitPointer(result);
372 digits[0] = (digit)(abs_ival & PyLong_MASK);
373 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
380 unsigned long t = abs_ival;
381 Py_ssize_t ndigits = 0;
389 if (unlikely(Py_ABS(Py_SIZE(*value)) < ndigits)) {
390 *value = Nuitka_LongRealloc(*value, ndigits);
393 CHECK_OBJECT(*value);
395 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)*value, ndigits, negative);
397 digit *d = Nuitka_LongGetDigitPointer(*value);
402 *d++ = (digit)(t & PyLong_MASK);
411static PyLongObject *Nuitka_LongStripZeros(PyLongObject *v) {
412 Py_ssize_t j = Py_ABS(Py_SIZE(v));
415 while (i > 0 && v->ob_digit[i - 1] == 0) {
420 Py_SIZE(v) = (Py_SIZE(v) < 0) ? -i : i;
427static PyLongObject *_Nuitka_LongAddDigits(digit
const *a, Py_ssize_t size_a, digit
const *b, Py_ssize_t size_b) {
429 if (size_a < size_b) {
431 digit
const *temp = a;
437 Py_ssize_t temp = size_a;
444 PyLongObject *result = Nuitka_LongNew(size_a + 1);
445 CHECK_OBJECT(result);
447 digit *r = Nuitka_LongGetDigitPointer(result);
453 for (i = 0; i < size_b; i++) {
454 carry += a[i] + b[i];
455 r[i] = carry & PyLong_MASK;
456 carry >>= PyLong_SHIFT;
459 for (; i < size_a; i++) {
461 r[i] = carry & PyLong_MASK;
462 carry >>= PyLong_SHIFT;
470 Nuitka_LongSetDigitSizeAndNegative(result, Nuitka_LongGetDigitSize(result) - 1,
false);
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);
484 if (size_a < size_b) {
491 Py_ssize_t temp = size_a;
501 for (i = 0; i < size_b; i++) {
502 carry += aa[i] + bb[i];
503 carry >>= PyLong_SHIFT;
507 Py_ssize_t needed = size_a;
509 for (; i < size_a; i++) {
511 carry >>= PyLong_SHIFT;
525 PyObject *old = left;
527 if (needed > Nuitka_LongGetDigitSize(left)) {
528 left = (PyObject *)Nuitka_LongNew(needed);
533 digit *r = Nuitka_LongGetDigitPointer(left);
539 for (i = 0; i < size_b; i++) {
540 carry += aa[i] + bb[i];
541 r[i] = carry & PyLong_MASK;
542 carry >>= PyLong_SHIFT;
545 for (; i < size_a; i++) {
547 r[i] = carry & PyLong_MASK;
548 carry >>= PyLong_SHIFT;
555 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i + 1,
false);
557 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i,
false);
566static PyLongObject *_Nuitka_LongSubDigits(digit
const *a, Py_ssize_t size_a, digit
const *b, Py_ssize_t size_b) {
571 if (size_a < size_b) {
575 digit
const *temp = a;
581 Py_ssize_t temp = size_a;
585 }
else if (size_a == size_b) {
587 Py_ssize_t i = size_a;
588 while (--i >= 0 && a[i] == b[i]) {
592#if PYTHON_VERSION < 0x300
593 return (PyLongObject *)Nuitka_LongFromCLong(0);
596 PyObject *result = Nuitka_Long_GetSmallValue(0);
598 return (PyLongObject *)result;
606 digit
const *temp = a;
612 size_a = size_b = i + 1;
615 PyLongObject *result = Nuitka_LongNew(size_a);
616 CHECK_OBJECT(result);
618 digit *r = Nuitka_LongGetDigitPointer(result);
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;
631 for (; i < size_a; i++) {
632 borrow = a[i] - borrow;
633 r[i] = borrow & PyLong_MASK;
634 borrow >>= PyLong_SHIFT;
640 while (i > 0 && r[i - 1] == 0) {
644 Nuitka_LongSetDigitSizeAndNegative(result, i, sign < 0);
646#if PYTHON_VERSION >= 0x300
649 medium_result_value_t ival = MEDIUM_VALUE(result);
651 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
654 result = (PyLongObject *)Nuitka_Long_GetSmallValue(ival);
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);
671 if (size_a < size_b) {
681 Py_ssize_t temp = size_a;
685 }
else if (size_a == size_b) {
687 Py_ssize_t i = size_a;
688 while (--i >= 0 && a[i] == b[i]) {
693#if PYTHON_VERSION < 0x300
694 PyObject *r = const_long_0;
696 PyObject *r = Nuitka_Long_GetSmallValue(0);
713 size_a = size_b = i + 1;
716 Py_ssize_t needed = size_a;
719 PyObject *old = left;
721 if (needed > Nuitka_LongGetDigitSize(left)) {
722 left = (PyObject *)Nuitka_LongNew(needed);
727 digit *r = Nuitka_LongGetDigitPointer(left);
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;
740 for (; i < size_a; i++) {
741 borrow = aa[i] - borrow;
742 r[i] = borrow & PyLong_MASK;
743 borrow >>= PyLong_SHIFT;
749 while (i > 0 && r[i - 1] == 0) {
753 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i, (sign < 0));
758#if PYTHON_VERSION >= 0x300
761 medium_result_value_t ival = MEDIUM_VALUE(left);
763 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
766 left = Nuitka_Long_GetSmallValue(ival);