From b66981604baf59ea465027cc10baa42af7c76571 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 9 Nov 2013 07:48:42 +0100 Subject: [PATCH] make fast path in Get/SetItemInt() utility functions safe for sizeof(index type) >= sizeof(Py_ssize_t) --- Cython/Compiler/ExprNodes.py | 8 ++------ Cython/Utility/ObjectHandling.c | 24 ++++++++++++------------ Cython/Utility/StringTools.c | 18 +++++++++--------- Cython/Utility/TypeConversion.c | 8 ++++++++ 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 8cd9ffb..c041053 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -3260,10 +3260,6 @@ class IndexNode(ExprNode): def extra_index_params(self, code): if self.index.type.is_int: - if self.original_index_type.signed: - size_adjustment = "" - else: - size_adjustment = "+1" is_list = self.base.type is list_type wraparound = ( bool(code.globalstate.directives['wraparound']) and @@ -3271,9 +3267,9 @@ class IndexNode(ExprNode): not (isinstance(self.index.constant_result, (int, long)) and self.index.constant_result >= 0)) boundscheck = bool(code.globalstate.directives['boundscheck']) - return ", sizeof(%s)%s, %s, %d, %d, %d" % ( + return ", %s, %d, %s, %d, %d, %d" % ( self.original_index_type.declaration_code(""), - size_adjustment, + self.original_index_type.signed and 1 or 0, self.original_index_type.to_py_function, is_list, wraparound, boundscheck) else: diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c index b83cab3..cf263ae 100644 --- a/Cython/Utility/ObjectHandling.c +++ b/Cython/Utility/ObjectHandling.c @@ -247,15 +247,15 @@ static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { /////////////// GetItemInt.proto /////////////// -#define __Pyx_GetItemInt(o, i, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_GetItemInt_Fast(o, i, is_list, wraparound, boundscheck) : \ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i))) {{for type in ['List', 'Tuple']}} -#define __Pyx_GetItemInt_{{type}}(o, i, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_GetItemInt_{{type}}_Fast(o, i, wraparound, boundscheck) : \ +#define __Pyx_GetItemInt_{{type}}(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_{{type}}_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i))) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_{{type}}_Fast(PyObject *o, Py_ssize_t i, @@ -340,9 +340,9 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, /////////////// SetItemInt.proto /////////////// -#define __Pyx_SetItemInt(o, i, v, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_SetItemInt_Fast(o, i, v, is_list, wraparound, boundscheck) : \ +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)) static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); @@ -405,9 +405,9 @@ static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObje /////////////// DelItemInt.proto /////////////// -#define __Pyx_DelItemInt(o, i, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_DelItemInt_Fast(o, i, is_list, wraparound) : \ +#define __Pyx_DelItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_DelItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound) : \ __Pyx_DelItem_Generic(o, to_py_func(i))) static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j); diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c index feb7910..4b2c549 100644 --- a/Cython/Utility/StringTools.c +++ b/Cython/Utility/StringTools.c @@ -229,9 +229,9 @@ static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int eq //////////////////// GetItemIntByteArray.proto //////////////////// -#define __Pyx_GetItemInt_ByteArray(o, i, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_GetItemInt_ByteArray_Fast(o, i, wraparound, boundscheck) : \ +#define __Pyx_GetItemInt_ByteArray(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ __Pyx_GetItemInt_ByteArray_Generic(o, to_py_func(i))) static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, @@ -272,9 +272,9 @@ static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Generic(PyObject* string, Py //////////////////// SetItemIntByteArray.proto //////////////////// -#define __Pyx_SetItemInt_ByteArray(o, i, v, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_SetItemInt_ByteArray_Fast(o, i, v, wraparound, boundscheck) : \ +#define __Pyx_SetItemInt_ByteArray(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_SetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, v, wraparound, boundscheck) : \ __Pyx_SetItemInt_ByteArray_Generic(o, to_py_func(i), v)) static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v, @@ -320,9 +320,9 @@ static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Generic(PyObject* string, Py //////////////////// GetItemIntUnicode.proto //////////////////// -#define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func, is_list, wraparound, boundscheck) \ - (((size) <= sizeof(Py_ssize_t)) ? \ - __Pyx_GetItemInt_Unicode_Fast(o, i, wraparound, boundscheck) : \ +#define __Pyx_GetItemInt_Unicode(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ + __Pyx_GetItemInt_Unicode_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i))) static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i, diff --git a/Cython/Utility/TypeConversion.c b/Cython/Utility/TypeConversion.c index 2a41caa..b8dcaa5 100644 --- a/Cython/Utility/TypeConversion.c +++ b/Cython/Utility/TypeConversion.c @@ -2,6 +2,14 @@ /* Type Conversion Predeclarations */ +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \ + (sizeof(type) < sizeof(Py_ssize_t)) || \ + (sizeof(type) > sizeof(Py_ssize_t) && \ + likely(v <= (type)PY_SSIZE_T_MAX) && \ + (!is_signed || likely(v >= (type)PY_SSIZE_T_MIN))) || \ + (sizeof(type) == sizeof(Py_ssize_t) && \ + (is_signed || likely(v <= (type)PY_SSIZE_T_MAX))) ) + static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -- 2.7.4