diff -r 6c54ca49c2af Cython/Compiler/PyrexTypes.py --- a/Cython/Compiler/PyrexTypes.py Thu Feb 26 00:38:33 2009 -0800 +++ b/Cython/Compiler/PyrexTypes.py Thu Feb 26 21:22:02 2009 -0200 @@ -495,11 +495,38 @@ int_conversion_list = {} -type_conversion_functions = "" type_conversion_predeclarations = "" +type_conversion_functions = """ +#define __PYX_PYINT_TYPE_CONVERSION_FUNC(c_type, c_name, signed) \\ +static INLINE c_type __pyx_PyInt_##c_name(PyObject* x) { \\ + if (sizeof(c_type) < sizeof(long)) { \\ + long long_val = __pyx_PyInt_AsLong(x); \\ + c_type val = (c_type) long_val; \\ + if (unlikely(long_val == -1 && PyErr_Occurred())) \\ + return (c_type)-1; \\ + else if (!signed && unlikely(long_val < 0)) { \\ + PyErr_SetString(PyExc_OverflowError, \\ + "can't convert negative value to "#c_type); \\ + return (c_type)-1; \\ + } \\ + if (unlikely(val != long_val)) { \\ + PyErr_SetString(PyExc_OverflowError, \\ + "value too large to convert to "#c_type); \\ + return (c_type)-1; \\ + } \\ + return val; \\ + } else { \\ + if (signed) \\ + return (c_type) __pyx_PyInt_AsLong(x); \\ + else \\ + return (c_type) __pyx_PyInt_AsUnsignedLong(x); \\ + } \\ +} + +""" class CIntType(CNumericType): - + is_int = 1 typedef_flag = 0 to_py_function = "PyInt_FromLong" @@ -515,36 +542,20 @@ def get_type_conversion(self): # error on overflow c_type = self.sign_and_name() - c_name = c_type.replace(' ', '_'); - func_name = "__pyx_PyInt_%s" % c_name; + c_name = c_type.replace(' ', '_') + func_name = "__pyx_PyInt_%s" % c_name if func_name not in int_conversion_list: + int_conversion_list[func_name] = True # no env to add utility code to global type_conversion_predeclarations, type_conversion_functions - if self.signed: - neg_test = "" - else: - neg_test = " || (long_val < 0)" - type_conversion_predeclarations += """ -static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name } - type_conversion_functions += """ -static INLINE %(c_type)s %(func_name)s(PyObject* x) { - if (sizeof(%(c_type)s) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - %(c_type)s val = (%(c_type)s)long_val; - if (unlikely((val != long_val) %(neg_test)s)) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s"); - return (%(c_type)s)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} -""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test } - int_conversion_list[func_name] = True + type_conversion_predeclarations += """\ +static INLINE %s __pyx_PyInt_%s(PyObject *); +""" % (c_type, c_name) + type_conversion_functions += """\ +__PYX_PYINT_TYPE_CONVERSION_FUNC(%s, %s, %d) +""" % (c_type, c_name, self.signed) return func_name - + def assignable_from_resolved_type(self, src_type): return src_type.is_int or src_type.is_enum or src_type is error_type @@ -558,20 +569,21 @@ class CAnonEnumType(CIntType): - is_enum = 1 + is_enum = 1 + def sign_and_name(self): + return 'int' class CUIntType(CIntType): to_py_function = "PyLong_FromUnsignedLong" - from_py_function = "PyInt_AsUnsignedLongMask" exception_value = -1 class CULongType(CUIntType): to_py_function = "PyLong_FromUnsignedLong" - from_py_function = "PyInt_AsUnsignedLongMask" + from_py_function = "__pyx_PyInt_AsUnsignedLong" class CLongLongType(CIntType): @@ -1397,9 +1409,12 @@ #endif #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x); -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x); -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x); +static INLINE int __Pyx_PyObject_IsTrue(PyObject*); + +#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x)) +static INLINE unsigned long __pyx_PyInt_AsUnsignedLong(PyObject*); +static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject*); +static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject*); #if !defined(T_PYSSIZET) #if PY_VERSION_HEX < 0x02050000 @@ -1429,17 +1444,111 @@ #endif #endif -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b); +static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject*); static INLINE PyObject * __pyx_PyInt_FromSize_t(size_t); static INLINE size_t __pyx_PyInt_AsSize_t(PyObject*); -#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x)) #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) + """ + type_conversion_predeclarations type_conversion_functions = """ /* Type Conversion Functions */ +static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + if (x == Py_True) return 1; + else if ((x == Py_False) | (x == Py_None)) return 0; + else return PyObject_IsTrue(x); +} + +static INLINE PyObject* __pyx_PyNumber_Int(PyObject* x) { +#if PY_VERSION_HEX < 0x03000000 + PyObject* tmp = PyNumber_Int(x); + if (tmp) return tmp; + else PyErr_Clear(); +#endif + return PyNumber_Long(x); +} + +static INLINE unsigned long __pyx_PyInt_AsUnsignedLong(PyObject* x) { +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_CheckExact(x) || PyInt_Check(x)) { + long val = PyInt_AS_LONG(x); + if (unlikely(val < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned long)-1; + } + return val; + } + else +#endif + if (PyLong_CheckExact(x) || PyLong_Check(x)) { + if (unlikely(Py_SIZE(x) < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned long)-1; + } + return PyLong_AsUnsignedLong(x); + } + else { + unsigned long val; + PyObject* tmp = __pyx_PyNumber_Int(x); if (!tmp) return (unsigned long)-1; + val = __pyx_PyInt_AsUnsignedLong(tmp); + Py_DECREF(tmp); + return val; + } +} + +static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) { +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_CheckExact(x) || PyInt_Check(x)) { + return PyInt_AS_LONG(x); + } + else +#endif + if (PyLong_CheckExact(x) || PyLong_Check(x)) { + return PyLong_AsLongLong(x); + } + else { + PY_LONG_LONG val; + PyObject* tmp = __pyx_PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; + val = __pyx_PyInt_AsLongLong(tmp); + Py_DECREF(tmp); + return val; + } +} + +static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) { +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_CheckExact(x) || PyInt_Check(x)) { + long val = PyInt_AS_LONG(x); + if (unlikely(val < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned PY_LONG_LONG)-1; + } + return val; + } + else +#endif + if (PyLong_CheckExact(x) || PyLong_Check(x)) { + if (unlikely(Py_SIZE(x) < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned PY_LONG_LONG)-1; + } + return PyLong_AsUnsignedLongLong(x); + } + else { + unsigned PY_LONG_LONG val; + PyObject *tmp = __pyx_PyNumber_Int(x); if (!tmp) return (unsigned PY_LONG_LONG)-1; + val = __pyx_PyInt_AsUnsignedLongLong(tmp); + Py_DECREF(tmp); + return val; + } +} + static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject* x = PyNumber_Index(b); @@ -1463,8 +1572,8 @@ #endif } -static INLINE size_t __pyx_PyInt_AsSize_t(PyObject* b) { - unsigned PY_LONG_LONG val = __pyx_PyInt_AsUnsignedLongLong(b); +static INLINE size_t __pyx_PyInt_AsSize_t(PyObject* x) { + unsigned PY_LONG_LONG val = __pyx_PyInt_AsUnsignedLongLong(x); if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) { return (size_t)-1; } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) { @@ -1474,63 +1583,4 @@ return val; } -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - if (x == Py_True) return 1; - else if ((x == Py_False) | (x == Py_None)) return 0; - else return PyObject_IsTrue(x); -} - -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) { -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_CheckExact(x)) { - return PyInt_AS_LONG(x); - } - else -#endif - if (PyLong_CheckExact(x)) { - return PyLong_AsLongLong(x); - } - else { - PY_LONG_LONG val; -#if PY_VERSION_HEX < 0x03000000 - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsLongLong(tmp); -#else - PyObject* tmp = PyNumber_Long(x); if (!tmp) return (PY_LONG_LONG)-1; - val = PyLong_AsLongLong(tmp); -#endif - Py_DECREF(tmp); - return val; - } -} - -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) { -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_CheckExact(x)) { - long val = PyInt_AS_LONG(x); - if (unlikely(val < 0)) { - PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned long long"); - return (unsigned PY_LONG_LONG)-1; - } - return val; - } - else -#endif - if (PyLong_CheckExact(x)) { - return PyLong_AsUnsignedLongLong(x); - } - else { - unsigned PY_LONG_LONG val; -#if PY_VERSION_HEX < 0x03000000 - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsUnsignedLongLong(tmp); -#else - PyObject* tmp = PyNumber_Long(x); if (!tmp) return (PY_LONG_LONG)-1; - val = PyLong_AsUnsignedLongLong(tmp); -#endif - Py_DECREF(tmp); - return val; - } -} - """ + type_conversion_functions