Skip to content

Commit

Permalink
Fix Python 3.11 and older
Browse files Browse the repository at this point in the history
  • Loading branch information
JukkaL committed May 20, 2024
1 parent 15a2ae3 commit f548b45
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 33 deletions.
54 changes: 54 additions & 0 deletions mypyc/lib-rt/pythonsupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "pythonsupport.h"

#if CPY_3_12_FEATURES

// Slow path of CPyLong_AsSsize_tAndOverflow (non-inlined)
Py_ssize_t
CPyLong_AsSsize_tAndOverflow_(PyObject *vv, int *overflow)
Expand Down Expand Up @@ -50,3 +52,55 @@ CPyLong_AsSsize_tAndOverflow_(PyObject *vv, int *overflow)
exit:
return res;
}

#else

// Slow path of CPyLong_AsSsize_tAndOverflow (non-inlined, Python 3.11 and earlier)
Py_ssize_t
CPyLong_AsSsize_tAndOverflow_(PyObject *vv, int *overflow)
{
/* This version by Tim Peters */
PyLongObject *v = (PyLongObject *)vv;
size_t x, prev;
Py_ssize_t res;
Py_ssize_t i;
int sign;

*overflow = 0;

res = -1;
i = Py_SIZE(v);

sign = 1;
x = 0;
if (i < 0) {
sign = -1;
i = -(i);
}
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) + CPY_LONG_DIGIT(v, i);
if ((x >> PyLong_SHIFT) != prev) {
*overflow = sign;
goto exit;
}
}
/* Haven't lost any bits, but casting to long requires extra
* care (see comment above).
*/
if (x <= (size_t)CPY_TAGGED_MAX) {
res = (Py_ssize_t)x * sign;
}
else if (sign < 0 && x == CPY_TAGGED_ABS_MIN) {
res = CPY_TAGGED_MIN;
}
else {
*overflow = sign;
/* res is already set to -1 */
}
exit:
return res;
}


#endif
40 changes: 7 additions & 33 deletions mypyc/lib-rt/pythonsupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ init_subclass(PyTypeObject *type, PyObject *kwds)
return 0;
}

#if CPY_3_12_FEATURES

Py_ssize_t
CPyLong_AsSsize_tAndOverflow_(PyObject *vv, int *overflow);

#if CPY_3_12_FEATURES

static inline Py_ssize_t
CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
{
Expand Down Expand Up @@ -161,7 +161,6 @@ CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
res = CPyLong_AsSsize_tAndOverflow_(vv, &overflow_local);
*overflow = overflow_local;
}
exit:
return res;
}

Expand All @@ -183,10 +182,8 @@ CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
{
/* This version by Tim Peters */
PyLongObject *v = (PyLongObject *)vv;
size_t x, prev;
Py_ssize_t res;
Py_ssize_t i;
int sign;

*overflow = 0;

Expand All @@ -200,35 +197,12 @@ CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
} else if (i == -1) {
res = -(sdigit)CPY_LONG_DIGIT(v, 0);
} else {
sign = 1;
x = 0;
if (i < 0) {
sign = -1;
i = -(i);
}
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) + CPY_LONG_DIGIT(v, i);
if ((x >> PyLong_SHIFT) != prev) {
*overflow = sign;
goto exit;
}
}
/* Haven't lost any bits, but casting to long requires extra
* care (see comment above).
*/
if (x <= (size_t)CPY_TAGGED_MAX) {
res = (Py_ssize_t)x * sign;
}
else if (sign < 0 && x == CPY_TAGGED_ABS_MIN) {
res = CPY_TAGGED_MIN;
}
else {
*overflow = sign;
/* res is already set to -1 */
}
// Slow path is moved to a non-inline helper function to
// limit size of generated code
int overflow_local;
res = CPyLong_AsSsize_tAndOverflow_(vv, &overflow_local);
*overflow = overflow_local;
}
exit:
return res;
}

Expand Down

0 comments on commit f548b45

Please sign in to comment.