8000 gh-129149: add macro PYLONG_FROM_INT · chris-eibl/cpython@37bddee · GitHub
[go: up one dir, main page]

Skip to content

Commit 37bddee

Browse files
committed
pythongh-129149: add macro PYLONG_FROM_INT
Use it in PyLong_FromLong() and PyLong_FromLongLong(). This is just a refactoring and will create the same binary code.
1 parent 3f2cfd0 commit 37bddee
< 10000 div class="prc-PageLayout-HorizontalDivider-CYLp5 prc-PageLayout-HeaderHorizontalDivider-bofyb" data-variant="line" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)">

File tree

1 file changed

+38
-68
lines changed

1 file changed

+38
-68
lines changed

Objects/longobject.c

Lines changed: 38 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -332,45 +332,48 @@ _PyLong_Negate(PyLongObject **x_p)
332332
Py_DECREF(x);
333333
}
334334

335+
#define PYLONG_FROM_INT(INT_TYPE, ival) \
336+
do { \
337+
PyLongObject *v; \
338+
unsigned INT_TYPE abs_ival, t; \
339+
int ndigits; \
340+
/* Handle small and medium cases. */ \
341+
if (IS_SMALL_INT(ival)) { \
342+
return get_small_int((sdigit)ival); \
343+
} \
344+
if (-(INT_TYPE)PyLong_MASK <= ival && ival <= (INT_TYPE)PyLong_MASK) { \
345+
return _PyLong_FromMedium((sdigit)ival); \
346+
} \
347+
/* Count digits (at least two - smaller cases were handled above). */ \
348+
abs_ival = ival < 0 ? 0U-(unsigned INT_TYPE)ival : (unsigned INT_TYPE)ival; \
349+
/* Do shift in two steps to avoid possible undefined behavior. */ \
350+
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; \
351+
ndigits = 2; \
352+
while (t) { \
353+
++ndigits; \
354+
t >>= PyLong_SHIFT; \
355+
} \
356+
/* Construct output value. */ \
357+
v = long_alloc(ndigits); \
358+
if (v != NULL) { \
359+
digit *p = v->long_value.ob_digit; \
360+
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits); \
361+
t = abs_ival; \
362+
while (t) { \
363+
*p++ = (digit)(t & PyLong_MASK); \
364+
t >>= PyLong_SHIFT; \
365+
} \
366+
} \
367+
return (PyObject *)v; \
368+
} while(0)
369+
370+
335371
/* Create a new int object from a C long int */
336372

337373
PyObject *
338374
PyLong_FromLong(long ival)
339375
{
340-
PyLongObject *v;
341-
unsigned long abs_ival, t;
342-
int ndigits;
343-
344-
/* Handle small and medium cases. */
345-
if (IS_SMALL_INT(ival)) {
346-
return get_small_int((sdigit)ival);
347-
}
348-
if (-(long)PyLong_MASK <= ival && ival <= (long)PyLong_MASK) {
349-
return _PyLong_FromMedium((sdigit)ival);
350-
}
351-
352-
/* Count digits (at least two - smaller cases were handled above). */
353-
abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival;
354-
/* Do shift in two steps to avoid possible undefined behavior. */
355-
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
356-
ndigits = 2;
357-
while (t) {
358-
++ndigits;
359-
t >>= PyLong_SHIFT;
360-
}
361-
362-
/* Construct output value. */
363-
v = long_alloc(ndigits);
364-
if (v != NULL) {
365-
digit *p = v->long_value.ob_digit;
366-
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
367-
t = abs_ival;
368-
while (t) {
369-
*p++ = (digit)(t & PyLong_MASK);
370-
t >>= PyLong_SHIFT;
371-
}
372-
}
373-
return (PyObject *)v;
376+
PYLONG_FROM_INT(long, ival);
374377
}
375378

376379
#define PYLONG_FROM_UINT(INT_TYPE, ival) \
@@ -1482,40 +1485,7 @@ PyLong_AsVoidPtr(PyObject *vv)
14821485
PyObject *
14831486
PyLong_FromLongLong(long long ival)
14841487
{
1485-
PyLongObject *v;
1486-
unsigned long long abs_ival, t;
1487-
int ndigits;
1488-
1489-
/* Handle small and medium cases. */
1490-
if (IS_SMALL_INT(ival)) {
1491-
return get_small_int((sdigit)ival);
1492-
}
1493-
if (-(long long)PyLong_MASK <= ival && ival <= (long long)PyLong_MASK) {
1494-
return _PyLong_FromMedium((sdigit)ival);
1495-
}
1496-
1497-
/* Count digits (at least two - smaller cases were handled above). */
1498-
abs_ival = ival < 0 ? 0U-(unsigned long long)ival : (unsigned long long)ival;
1499-
/* Do shift in two steps to avoid possible undefined behavior. */
1500-
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
1501-
ndigits = 2;
1502-
while (t) {
1503-
++ndigits;
1504-
t >>= PyLong_SHIFT;
1505-
}
1506-
1507-
/* Construct output value. */
1508-
v = long_alloc(ndigits);
1509-
if (v != NULL) {
1510-
digit *p = v->long_value.ob_digit;
1511-
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
1512-
t = abs_ival;
1513-
while (t) {
1514-
*p++ = (digit)(t & PyLong_MASK);
1515-
t >>= PyLong_SHIFT;
1516-
}
1517-
}
1518-
return (PyObject *)v;
1488+
PYLONG_FROM_INT(long long, ival);
15191489
}
15201490

15211491
/* Create a new int object from a C Py_ssize_t. */

0 commit comments

Comments
 (0)
0