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;
49#if PYTHON_VERSION < 0x3c0
50#define MAX_LONG_DIGITS ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit)) / sizeof(digit))
51#define Nuitka_LongGetDigitPointer(value) (&(((PyLongObject *)value)->ob_digit[0]))
52#define Nuitka_LongGetDigitSize(value) (Py_ABS(Py_SIZE(value)))
53#define Nuitka_LongGetSignedDigitSize(value) (Py_SIZE(value))
54#define Nuitka_LongIsNegative(value) (Py_SIZE(value) < 0)
55#define Nuitka_LongSetSignNegative(value) Py_SET_SIZE(value, -Py_ABS(Py_SIZE(value)))
56#define Nuitka_LongSetSign(value, positive) Py_SET_SIZE(value, (((positive) ? 1 : -1) * Py_ABS(Py_SIZE(value))))
57#define Nuitka_LongFlipSign(value) Py_SET_SIZE(value, -Py_SIZE(value))
58#define Nuitka_LongSetDigitSizeAndNegative(value, count, negative) Py_SET_SIZE(value, negative ? -count : count)
60#define MAX_LONG_DIGITS ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit)) / sizeof(digit))
62#define Nuitka_LongGetDigitPointer(value) (&(((PyLongObject *)value)->long_value.ob_digit[0]))
63#define Nuitka_LongGetDigitSize(value) (_PyLong_DigitCount((PyLongObject const *)(value)))
64#define Nuitka_LongGetSignedDigitSize(value) (_PyLong_SignedDigitCount((PyLongObject const *)(value)))
65#define Nuitka_LongIsNegative(value) (((PyLongObject *)value)->long_value.lv_tag & SIGN_NEGATIVE)
66#define Nuitka_LongSetSignNegative(value) \
67 ((PyLongObject *)value)->long_value.lv_tag = ((PyLongObject *)value)->long_value.lv_tag | SIGN_NEGATIVE;
68#define Nuitka_LongSetSignPositive(value) \
69 ((PyLongObject *)value)->long_value.lv_tag = ((PyLongObject *)value)->long_value.lv_tag & ~(SIGN_NEGATIVE);
70#define Nuitka_LongSetSign(value, positive) \
72 Nuitka_LongSetSignPositive(value); \
74 Nuitka_LongSetSignNegative(value); \
76#define Nuitka_LongSetDigitSizeAndNegative(value, count, negative) \
77 _PyLong_SetSignAndDigitCount(value, negative ? -1 : 1, count)
78#define Nuitka_LongFlipSign(value) _PyLong_FlipSign(value)
82static PyLongObject *Nuitka_LongNew(Py_ssize_t size) {
84 assert(size < (Py_ssize_t)MAX_LONG_DIGITS);
87#if PYTHON_VERSION >= 0x3c0
89 Py_ssize_t ndigits = size ? size : 1;
91 PyLongObject *result =
92 (PyLongObject *)NuitkaObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) + ndigits *
sizeof(digit));
93 _PyLong_SetSignAndDigitCount(result, size != 0, size);
94 PyObject_INIT(result, &PyLong_Type);
95 result->long_value.ob_digit[0] = 0;
97#elif PYTHON_VERSION >= 0x300
98 PyLongObject *result = (PyLongObject *)NuitkaObject_Malloc(offsetof(PyLongObject, ob_digit) + size *
sizeof(digit));
99 return (PyLongObject *)PyObject_INIT_VAR(result, &PyLong_Type, size);
101 return (PyLongObject *)PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
105static PyObject *Nuitka_LongRealloc(PyObject *value, Py_ssize_t size) {
108 PyLongObject *result = Nuitka_LongNew(size);
109 Nuitka_LongSetDigitSizeAndNegative(result, size,
false);
112 return (PyObject *)result;
115static PyObject *Nuitka_LongFromCLong(
long ival) {
116#if PYTHON_VERSION < 0x300
118 PyLongObject *result = Nuitka_LongNew(0);
120 return (PyObject *)result;
123 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
124 PyObject *result = Nuitka_Long_GetSmallValue(ival);
133 unsigned long abs_ival;
137 abs_ival = 0U - (
unsigned long)ival;
140 abs_ival = (
unsigned long)ival;
145 if (!(abs_ival >> PyLong_SHIFT)) {
146 PyLongObject *result = Nuitka_LongNew(1);
147 assert(result != NULL);
149 Nuitka_LongSetSignNegative(result);
152 digit *digits = Nuitka_LongGetDigitPointer(result);
153 digits[0] = (digit)abs_ival;
155 return (PyObject *)result;
159#if PyLong_SHIFT == 15
160 if (!(abs_ival >> 2 * PyLong_SHIFT)) {
161 PyLongObject *result = Nuitka_LongNew(2);
162 assert(result != NULL);
164 Nuitka_LongSetSignNegative(result);
167 digit *digits = Nuitka_LongGetDigitPointer(result);
169 digits[0] = (digit)(abs_ival & PyLong_MASK);
170 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
172 return (PyObject *)result;
177 unsigned long t = abs_ival;
178 Py_ssize_t ndigits = 0;
186 PyLongObject *result = _PyLong_New(ndigits);
187 assert(result != NULL);
189 Nuitka_LongSetDigitSizeAndNegative(result, ndigits, negative);
191 digit *d = Nuitka_LongGetDigitPointer(result);
196 *d++ = (digit)(t & PyLong_MASK);
200 return (PyObject *)result;
204PyObject *Nuitka_PyLong_FromLong(
long ival) {
return Nuitka_LongFromCLong(ival); }
206static void Nuitka_LongUpdateFromCLong(PyObject **value,
long ival) {
207 assert(Py_REFCNT(*value) == 1);
209#if PYTHON_VERSION < 0x300
211 if (Py_SIZE(*value) == 0) {
216 *value = (PyObject *)Nuitka_LongNew(0);
221 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
224 *value = Nuitka_Long_GetSmallValue(ival);
233 unsigned long abs_ival;
237 abs_ival = 0U - (
unsigned long)ival;
240 abs_ival = (
unsigned long)ival;
245 if (!(abs_ival >> PyLong_SHIFT)) {
246 PyLongObject *result;
248#if PYTHON_VERSION < 0x3c0
249 if (unlikely(Py_SIZE(*value) == 0)) {
250 *value = Nuitka_LongRealloc(*value, 1);
251 CHECK_OBJECT(*value);
253 result = (PyLongObject *)*value;
257 result = (PyLongObject *)(*value);
260 Nuitka_LongSetSign(result, !negative);
262 digit *digits = Nuitka_LongGetDigitPointer(result);
263 digits[0] = (digit)abs_ival;
269#if PyLong_SHIFT == 15
270 if (!(abs_ival >> 2 * PyLong_SHIFT)) {
271 PyLongObject *result;
272 if (unlikely(Py_ABS(Py_SIZE(*value)) < 2)) {
273 *value = Nuitka_LongRealloc(*value, 2);
274 CHECK_OBJECT(*value);
276 result = (PyLongObject *)*value;
278 result = (PyLongObject *)(*value);
282 Nuitka_LongSetSignNegative(result);
285 digit *digits = Nuitka_LongGetDigitPointer(result);
287 digits[0] = (digit)(abs_ival & PyLong_MASK);
288 digits[1] = (digit)(abs_ival >> PyLong_SHIFT);
295 unsigned long t = abs_ival;
296 Py_ssize_t ndigits = 0;
304 if (unlikely(Py_ABS(Py_SIZE(*value)) < ndigits)) {
305 *value = Nuitka_LongRealloc(*value, ndigits);
308 CHECK_OBJECT(*value);
310 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)*value, ndigits, negative);
312 digit *d = Nuitka_LongGetDigitPointer(*value);
317 *d++ = (digit)(t & PyLong_MASK);
326static PyLongObject *Nuitka_LongStripZeros(PyLongObject *v) {
327 Py_ssize_t j = Py_ABS(Py_SIZE(v));
330 while (i > 0 && v->ob_digit[i - 1] == 0) {
335 Py_SIZE(v) = (Py_SIZE(v) < 0) ? -i : i;
342static PyLongObject *_Nuitka_LongAddDigits(digit
const *a, Py_ssize_t size_a, digit
const *b, Py_ssize_t size_b) {
344 if (size_a < size_b) {
346 digit
const *temp = a;
352 Py_ssize_t temp = size_a;
359 PyLongObject *result = Nuitka_LongNew(size_a + 1);
360 CHECK_OBJECT(result);
362 digit *r = Nuitka_LongGetDigitPointer(result);
368 for (i = 0; i < size_b; i++) {
369 carry += a[i] + b[i];
370 r[i] = carry & PyLong_MASK;
371 carry >>= PyLong_SHIFT;
374 for (; i < size_a; i++) {
376 r[i] = carry & PyLong_MASK;
377 carry >>= PyLong_SHIFT;
385 Nuitka_LongSetDigitSizeAndNegative(result, Nuitka_LongGetDigitSize(result) - 1,
false);
391static PyObject *_Nuitka_LongAddInplaceDigits(PyObject *left, digit
const *b, Py_ssize_t size_b) {
392 digit
const *a = Nuitka_LongGetDigitPointer(left);
393 Py_ssize_t size_a = Nuitka_LongGetDigitSize(left);
399 if (size_a < size_b) {
406 Py_ssize_t temp = size_a;
416 for (i = 0; i < size_b; i++) {
417 carry += aa[i] + bb[i];
418 carry >>= PyLong_SHIFT;
422 Py_ssize_t needed = size_a;
424 for (; i < size_a; i++) {
426 carry >>= PyLong_SHIFT;
440 PyObject *old = left;
442 if (needed > Nuitka_LongGetDigitSize(left)) {
443 left = (PyObject *)Nuitka_LongNew(needed);
448 digit *r = Nuitka_LongGetDigitPointer(left);
454 for (i = 0; i < size_b; i++) {
455 carry += aa[i] + bb[i];
456 r[i] = carry & PyLong_MASK;
457 carry >>= PyLong_SHIFT;
460 for (; i < size_a; i++) {
462 r[i] = carry & PyLong_MASK;
463 carry >>= PyLong_SHIFT;
470 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i + 1,
false);
472 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i,
false);
481static PyLongObject *_Nuitka_LongSubDigits(digit
const *a, Py_ssize_t size_a, digit
const *b, Py_ssize_t size_b) {
486 if (size_a < size_b) {
490 digit
const *temp = a;
496 Py_ssize_t temp = size_a;
500 }
else if (size_a == size_b) {
502 Py_ssize_t i = size_a;
503 while (--i >= 0 && a[i] == b[i]) {
507#if PYTHON_VERSION < 0x300
508 return (PyLongObject *)Nuitka_LongFromCLong(0);
511 PyObject *result = Nuitka_Long_GetSmallValue(0);
513 return (PyLongObject *)result;
521 digit
const *temp = a;
527 size_a = size_b = i + 1;
530 PyLongObject *result = Nuitka_LongNew(size_a);
531 CHECK_OBJECT(result);
533 digit *r = Nuitka_LongGetDigitPointer(result);
539 for (i = 0; i < size_b; i++) {
540 borrow = a[i] - b[i] - borrow;
541 r[i] = borrow & PyLong_MASK;
542 borrow >>= PyLong_SHIFT;
546 for (; i < size_a; i++) {
547 borrow = a[i] - borrow;
548 r[i] = borrow & PyLong_MASK;
549 borrow >>= PyLong_SHIFT;
555 while (i > 0 && r[i - 1] == 0) {
559 Nuitka_LongSetDigitSizeAndNegative(result, i, sign < 0);
561#if PYTHON_VERSION >= 0x300
564 medium_result_value_t ival = MEDIUM_VALUE(result);
566 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
569 result = (PyLongObject *)Nuitka_Long_GetSmallValue(ival);
578static PyObject *_Nuitka_LongSubInplaceDigits(PyObject *left, digit
const *b, Py_ssize_t size_b,
int sign) {
579 digit
const *a = Nuitka_LongGetDigitPointer(left);
580 Py_ssize_t size_a = Nuitka_LongGetDigitSize(left);
586 if (size_a < size_b) {
596 Py_ssize_t temp = size_a;
600 }
else if (size_a == size_b) {
602 Py_ssize_t i = size_a;
603 while (--i >= 0 && a[i] == b[i]) {
608#if PYTHON_VERSION < 0x300
609 PyObject *r = const_long_0;
611 PyObject *r = Nuitka_Long_GetSmallValue(0);
628 size_a = size_b = i + 1;
631 Py_ssize_t needed = size_a;
634 PyObject *old = left;
636 if (needed > Nuitka_LongGetDigitSize(left)) {
637 left = (PyObject *)Nuitka_LongNew(needed);
642 digit *r = Nuitka_LongGetDigitPointer(left);
648 for (i = 0; i < size_b; i++) {
649 borrow = aa[i] - bb[i] - borrow;
650 r[i] = borrow & PyLong_MASK;
651 borrow >>= PyLong_SHIFT;
655 for (; i < size_a; i++) {
656 borrow = aa[i] - borrow;
657 r[i] = borrow & PyLong_MASK;
658 borrow >>= PyLong_SHIFT;
664 while (i > 0 && r[i - 1] == 0) {
668 Nuitka_LongSetDigitSizeAndNegative((PyLongObject *)left, i, (sign < 0));
673#if PYTHON_VERSION >= 0x300
676 medium_result_value_t ival = MEDIUM_VALUE(left);
678 if (ival >= NUITKA_STATIC_SMALLINT_VALUE_MIN && ival < NUITKA_STATIC_SMALLINT_VALUE_MAX) {
681 left = Nuitka_Long_GetSmallValue(ival);