diff -r 474a2405291b Cython/Compiler/ModuleNode.py --- a/Cython/Compiler/ModuleNode.py Sun Mar 08 14:18:27 2009 +0100 +++ b/Cython/Compiler/ModuleNode.py Mon Mar 09 10:18:54 2009 -0200 @@ -537,8 +537,8 @@ self.generate_includes(env, cimported_modules, code) code.putln('') code.put(Nodes.utility_function_predeclarations) + code.put(Nodes.branch_prediction_macros) code.put(PyrexTypes.type_conversion_predeclarations) - code.put(Nodes.branch_prediction_macros) code.putln('') code.putln('static PyObject *%s;' % env.module_cname) code.putln('static PyObject *%s;' % Naming.builtins_cname) diff -r 474a2405291b Cython/Compiler/PyrexTypes.py --- a/Cython/Compiler/PyrexTypes.py Sun Mar 08 14:18:27 2009 +0100 +++ b/Cython/Compiler/PyrexTypes.py Mon Mar 09 10:18:54 2009 -0200 @@ -496,55 +496,71 @@ return self.base_declaration_code(base, entity_code) -int_conversion_list = {} -type_conversion_functions = "" +type_conversion_list = {} type_conversion_predeclarations = "" +type_conversion_functions = """ +#define __PYX_PYINT_CTYPE_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((long)val != long_val)) { \\ + PyErr_SetString(PyExc_OverflowError, \\ + "value too large to convert to "#c_type); \\ + return (c_type)-1; \\ + } \\ + return val; \\ + } else if (sizeof(c_type) == sizeof(long)) { \\ + if (SIGNED) \\ + return (c_type) __pyx_PyInt_AsLong(x); \\ + else \\ + return (c_type) __pyx_PyInt_AsUnsignedLong(x); \\ + } else {/*(sizeof(c_type) > sizeof(long))*/ \\ + if (SIGNED) \\ + return (c_type) __pyx_PyInt_AsLongLong(x); \\ + else \\ + return (c_type) __pyx_PyInt_AsUnsignedLongLong(x); \\ + } \\ +} + +""" class CIntType(CNumericType): is_int = 1 typedef_flag = 0 to_py_function = "PyInt_FromLong" - from_py_function = "__pyx_PyInt_AsLong" + from_py_function = "__pyx_PyInt_AsInt" exception_value = -1 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0): CNumericType.__init__(self, rank, signed, pymemberdef_typecode) self.is_returncode = is_returncode - if self.from_py_function == '__pyx_PyInt_AsLong': + if self.from_py_function == '__pyx_PyInt_AsInt': self.from_py_function = self.get_type_conversion() 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; - if func_name not in int_conversion_list: + c_name = c_type.replace(' ', '_') + func_name = "__pyx_PyInt_%s" % c_name + if func_name not in type_conversion_list: + type_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_CTYPE_CONVERSION_FUNC(%s, %s, %d) +""" % (c_type, c_name, self.signed) return func_name def assignable_from_resolved_type(self, src_type): @@ -560,20 +576,28 @@ 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 CLongType(CIntType): + + to_py_function = "PyInt_FromLong" + from_py_function = "__pyx_PyInt_AsLong" + + class CULongType(CUIntType): to_py_function = "PyLong_FromUnsignedLong" - from_py_function = "PyInt_AsUnsignedLongMask" + from_py_function = "__pyx_PyInt_AsUnsignedLong" class CLongLongType(CIntType): @@ -593,7 +617,7 @@ class CPySSizeTType(CIntType): to_py_function = "PyInt_FromSsize_t" - from_py_function = "__pyx_PyIndex_AsSsize_t" + from_py_function = "__Pyx_PyIndex_AsSsize_t" def sign_and_name(self): return rank_to_type_name[self.rank] @@ -601,8 +625,8 @@ class CSizeTType(CUIntType): - to_py_function = "__pyx_PyInt_FromSize_t" - from_py_function = "__pyx_PyInt_AsSize_t" + to_py_function = "__Pyx_PyInt_FromSize_t" + from_py_function = "__Pyx_PyInt_AsSize_t" def sign_and_name(self): return rank_to_type_name[self.rank] @@ -1196,14 +1220,14 @@ c_char_type = CIntType(0, 1, "T_CHAR") c_short_type = CIntType(1, 1, "T_SHORT") c_int_type = CIntType(2, 1, "T_INT") -c_long_type = CIntType(3, 1, "T_LONG") +c_long_type = CLongType(3, 1, "T_LONG") c_longlong_type = CLongLongType(6, 1, "T_LONGLONG") c_bint_type = CBIntType(2, 1, "T_INT") c_schar_type = CIntType(0, 2, "T_CHAR") c_sshort_type = CIntType(1, 2, "T_SHORT") c_sint_type = CIntType(2, 2, "T_INT") -c_slong_type = CIntType(3, 2, "T_LONG") +c_slong_type = CLongType(3, 2, "T_LONG") c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG") c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET") @@ -1235,23 +1259,23 @@ sign_and_rank_to_type = { #(signed, rank) - (0, 0): c_uchar_type, - (0, 1): c_ushort_type, - (0, 2): c_uint_type, + (0, 0): c_uchar_type, + (0, 1): c_ushort_type, + (0, 2): c_uint_type, (0, 3): c_ulong_type, (0, 6): c_ulonglong_type, - (1, 0): c_char_type, - (1, 1): c_short_type, - (1, 2): c_int_type, + (1, 0): c_char_type, + (1, 1): c_short_type, + (1, 2): c_int_type, (1, 3): c_long_type, (1, 6): c_longlong_type, - (2, 0): c_schar_type, - (2, 1): c_sshort_type, - (2, 2): c_sint_type, + (2, 0): c_schar_type, + (2, 1): c_sshort_type, + (2, 2): c_sint_type, (2, 3): c_slong_type, - (2, 6): c_slonglong_type, + (2, 6): c_slonglong_type, (0, 4): c_py_ssize_t_type, (1, 4): c_py_ssize_t_type, @@ -1260,36 +1284,36 @@ (1, 5): c_size_t_type, (2, 5): c_size_t_type, - (1, 7): c_float_type, + (1, 7): c_float_type, (1, 8): c_double_type, (1, 9): c_longdouble_type, # In case we're mixing unsigned ints and floats... - (0, 7): c_float_type, + (0, 7): c_float_type, (0, 8): c_double_type, (0, 9): c_longdouble_type, } modifiers_and_name_to_type = { #(signed, longness, name) - (0, 0, "char"): c_uchar_type, - (0, -1, "int"): c_ushort_type, - (0, 0, "int"): c_uint_type, + (0, 0, "char"): c_uchar_type, + (0, -1, "int"): c_ushort_type, + (0, 0, "int"): c_uint_type, (0, 1, "int"): c_ulong_type, (0, 2, "int"): c_ulonglong_type, (1, 0, "void"): c_void_type, - (1, 0, "char"): c_char_type, - (1, -1, "int"): c_short_type, - (1, 0, "int"): c_int_type, + (1, 0, "char"): c_char_type, + (1, -1, "int"): c_short_type, + (1, 0, "int"): c_int_type, (1, 1, "int"): c_long_type, (1, 2, "int"): c_longlong_type, - (1, 0, "float"): c_float_type, + (1, 0, "float"): c_float_type, (1, 0, "double"): c_double_type, (1, 1, "double"): c_longdouble_type, (1, 0, "object"): py_object_type, - (1, 0, "bint"): c_bint_type, - (2, 0, "char"): c_schar_type, - (2, -1, "int"): c_sshort_type, - (2, 0, "int"): c_sint_type, + (1, 0, "bint"): c_bint_type, + (2, 0, "char"): c_schar_type, + (2, -1, "int"): c_sshort_type, + (2, 0, "int"): c_sint_type, (2, 1, "int"): c_slong_type, (2, 2, "int"): c_slonglong_type, @@ -1407,9 +1431,28 @@ #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*); + +#if PY_MAJOR_VERSION < 3 +#define __pyx_PyInt_AsLong(x) \\ + (PyInt_CheckExact(x) ? (long) PyInt_AS_LONG(x) : __Pyx_PyInt_AsLong(x)) +#define __pyx_PyInt_AsUnsignedLong(x) \\ + ((PyInt_CheckExact(x) && PyInt_AS_LONG(x) >= 0) ? (unsigned long) PyInt_AS_LONG(x) : __Pyx_PyInt_AsUnsignedLong(x)) +#define __pyx_PyInt_AsLongLong(x) \ + (PyInt_CheckExact(x) ? (PY_LONG_LONG) PyInt_AS_LONG(x) : __Pyx_PyInt_AsLongLong(x)) +#define __pyx_PyInt_AsUnsignedLongLong(x) \\ + ((PyInt_CheckExact(x) && PyInt_AS_LONG(x) >= 0) ? (unsigned PY_LONG_LONG) PyInt_AS_LONG(x) : __Pyx_PyInt_AsUnsignedLongLong(x)) +#else +#define __pyx_PyInt_AsLong(x) __Pyx_PyInt_AsLong(x) +#define __pyx_PyInt_AsUnsignedLong(x) __Pyx_PyInt_AsUnsignedLong(x) +#define __pyx_PyInt_AsLongLong(x) __Pyx_PyInt_AsLongLong(x) +#define __pyx_PyInt_AsUnsignedLongLong(x) __Pyx_PyInt_AsUnsignedLongLong(x) +#endif + +static INLINE long __Pyx_PyInt_AsLong(PyObject*); +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 @@ -1439,18 +1482,131 @@ #endif #endif -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b); -static INLINE PyObject * __pyx_PyInt_FromSize_t(size_t); -static INLINE size_t __pyx_PyInt_AsSize_t(PyObject*); +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 Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) { +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 long __Pyx_PyInt_AsLong(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_AsLong(x); + } + else { + long val; + PyObject* tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; + val = __Pyx_PyInt_AsLong(tmp); + Py_DECREF(tmp); + return val; + } +} + +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); if (!x) return -1; @@ -1459,7 +1615,7 @@ return ival; } -static INLINE PyObject * __pyx_PyInt_FromSize_t(size_t ival) { +static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { #if PY_VERSION_HEX < 0x02050000 if (ival <= LONG_MAX) return PyInt_FromLong((long)ival); @@ -1473,8 +1629,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)) { @@ -1484,63 +1640,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