make fast path in Get/SetItemInt() utility functions safe for sizeof(index type)...
authorStefan Behnel <stefan_ml@behnel.de>
Sat, 9 Nov 2013 06:48:42 +0000 (07:48 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Sat, 9 Nov 2013 06:48:42 +0000 (07:48 +0100)
Cython/Compiler/ExprNodes.py
Cython/Utility/ObjectHandling.c
Cython/Utility/StringTools.c
Cython/Utility/TypeConversion.c

index 8cd9ffb..c041053 100644 (file)
@@ -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:
index b83cab3..cf263ae 100644 (file)
@@ -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);
index feb7910..4b2c549 100644 (file)
@@ -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,
index 2a41caa..b8dcaa5 100644 (file)
@@ -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);