Commit 67c64fe1 authored by Stefan Behnel's avatar Stefan Behnel

guard against incorrect values for PYLONG_BITS_IN_DIGIT that do not match CPython's

parent 900dfde0
...@@ -506,6 +506,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -506,6 +506,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/* Generated by Cython %s */" % Version.watermark) code.putln("/* Generated by Cython %s */" % Version.watermark)
code.putln("") code.putln("")
code.putln("#define PY_SSIZE_T_CLEAN") code.putln("#define PY_SSIZE_T_CLEAN")
# sizeof(PyLongObject.ob_digit[0]) may have been determined dynamically
# at compile time in CPython, in which case we can't know the correct
# storage size for an installed system. We can rely on it only if
# pyconfig.h defines it statically, i.e. if it was set by "configure".
# Once we include "Python.h", it will come up with its own idea about
# a suitable value, which may or may not match the real one.
code.putln("#ifndef CYTHON_USE_PYLONG_INTERNALS")
code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
# assume it's an incorrect left-over
code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
code.putln("#else")
code.putln('#include "pyconfig.h"')
code.putln("#ifdef PYLONG_BITS_IN_DIGIT")
code.putln("#define CYTHON_USE_PYLONG_INTERNALS 1")
code.putln("#else")
code.putln("#define CYTHON_USE_PYLONG_INTERNALS 0")
code.putln("#endif")
code.putln("#endif")
code.putln("#endif")
for filename in env.python_include_files: for filename in env.python_include_files:
code.putln('#include "%s"' % filename) code.putln('#include "%s"' % filename)
code.putln("#ifndef Py_PYTHON_H") code.putln("#ifndef Py_PYTHON_H")
......
...@@ -1386,8 +1386,10 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *) ...@@ -1386,8 +1386,10 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *)
""", """,
impl=""" impl="""
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
#include "longintrepr.h" #include "longintrepr.h"
#endif #endif
#endif
static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, const_zero = 0; const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero; const int is_unsigned = neg_one > const_zero;
...@@ -1405,12 +1407,14 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x ...@@ -1405,12 +1407,14 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x
if (likely(PyLong_Check(x))) { if (likely(PyLong_Check(x))) {
if (is_unsigned) { if (is_unsigned) {
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
if (sizeof(digit) <= sizeof(%(type)s)) { if (sizeof(digit) <= sizeof(%(type)s)) {
switch (Py_SIZE(x)) { switch (Py_SIZE(x)) {
case 0: return 0; case 0: return 0;
case 1: return (%(type)s) ((PyLongObject*)x)->ob_digit[0]; case 1: return (%(type)s) ((PyLongObject*)x)->ob_digit[0];
} }
} }
#endif
#endif #endif
if (unlikely(Py_SIZE(x) < 0)) { if (unlikely(Py_SIZE(x) < 0)) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
...@@ -1420,6 +1424,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x ...@@ -1420,6 +1424,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x
return (%(type)s)PyLong_AsUnsigned%(TypeName)s(x); return (%(type)s)PyLong_AsUnsigned%(TypeName)s(x);
} else { } else {
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
if (sizeof(digit) <= sizeof(%(type)s)) { if (sizeof(digit) <= sizeof(%(type)s)) {
switch (Py_SIZE(x)) { switch (Py_SIZE(x)) {
case 0: return 0; case 0: return 0;
...@@ -1427,6 +1432,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x ...@@ -1427,6 +1432,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x
case -1: return -(%(type)s) ((PyLongObject*)x)->ob_digit[0]; case -1: return -(%(type)s) ((PyLongObject*)x)->ob_digit[0];
} }
} }
#endif
#endif #endif
return (%(type)s)PyLong_As%(TypeName)s(x); return (%(type)s)PyLong_As%(TypeName)s(x);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment