From 67c64fe1314eea3eb15c7e299038f70c294104bf Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 9 Mar 2013 20:27:36 +0100 Subject: [PATCH] guard against incorrect values for PYLONG_BITS_IN_DIGIT that do not match CPython's --- Cython/Compiler/ModuleNode.py | 21 +++++++++++++++++++++ Cython/Compiler/PyrexTypes.py | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 5021754..cc29143 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -506,6 +506,27 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("/* Generated by Cython %s */" % Version.watermark) code.putln("") 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: code.putln('#include "%s"' % filename) code.putln("#ifndef Py_PYTHON_H") diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index ab6e3a9..10cfaf4 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -1386,8 +1386,10 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *) """, impl=""" #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 +#if CYTHON_USE_PYLONG_INTERNALS #include "longintrepr.h" #endif +#endif 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 int is_unsigned = neg_one > const_zero; @@ -1405,6 +1407,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 +#if CYTHON_USE_PYLONG_INTERNALS if (sizeof(digit) <= sizeof(%(type)s)) { switch (Py_SIZE(x)) { case 0: return 0; @@ -1412,6 +1415,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x } } #endif +#endif if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to %(type)s"); @@ -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); } else { #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 +#if CYTHON_USE_PYLONG_INTERNALS if (sizeof(digit) <= sizeof(%(type)s)) { switch (Py_SIZE(x)) { case 0: return 0; @@ -1428,6 +1433,7 @@ static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x } } #endif +#endif return (%(type)s)PyLong_As%(TypeName)s(x); } } else { -- 2.7.4