Fix some integer conversion tests.
authorRobert Bradshaw <robertwb@gmail.com>
Mon, 26 Aug 2013 17:48:32 +0000 (10:48 -0700)
committerRobert Bradshaw <robertwb@gmail.com>
Mon, 26 Aug 2013 22:02:55 +0000 (15:02 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/PyrexTypes.py
Cython/Utility/TypeConversion.c
tests/run/cpp_nonstdint.h
tests/run/int_literals.pyx
tests/run/wundram1.pyx

index 7f1fdcb..b6d614e 100755 (executable)
@@ -3019,6 +3019,7 @@ class IndexNode(ExprNode):
                     else:
                         self.is_temp = 1
                     self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
+                    self.original_index_type.create_to_py_utility_code(env)
                 else:
                     self.index = self.index.coerce_to_pyobject(env)
                     self.is_temp = 1
index 6ae12a7..a19124f 100644 (file)
@@ -589,6 +589,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_type.title())
         code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0])
         
+        # These utility functions are assumed to exist and used elsewhere.
+        PyrexTypes.c_long_type.create_to_py_utility_code(env)
+        PyrexTypes.c_long_type.create_from_py_utility_code(env)
+        
         code.put(Nodes.branch_prediction_macros)
         code.putln('')
         code.putln('static PyObject *%s;' % env.module_cname)
index 492ae56..3d9b77b 100755 (executable)
@@ -368,11 +368,11 @@ class CTypedefType(BaseType):
             if not self.to_py_utility_code:
                 base_type = self.typedef_base_type
                 if type(base_type) is CIntType:
-                    self.from_py_function = "__Pyx_PyInt_from_py_" + self.specialization_name()
+                    self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
                     env.use_utility_code(TempitaUtilityCode.load(
-                        "CIntFromPy", "TypeConversion.c",
+                        "CIntToPy", "TypeConversion.c",
                         context={"TYPE": self.declaration_code(''),
-                                 "FROM_PY_FUNCTION": self.from_py_function}))
+                                 "TO_PY_FUNCTION": self.to_py_function}))
                     return True
                 elif base_type.is_float:
                     pass # XXX implement!
@@ -390,11 +390,11 @@ class CTypedefType(BaseType):
             if not self.from_py_utility_code:
                 base_type = self.typedef_base_type
                 if type(base_type) is CIntType:
-                    self.to_py_function = "__Pyx_PyInt_to_py_" + self.specialization_name()
+                    self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
                     env.use_utility_code(TempitaUtilityCode.load(
-                        "CIntToPy", "TypeConversion.c",
+                        "CIntFromPy", "TypeConversion.c",
                         context={"TYPE": self.declaration_code(''),
-                                 "TO_PY_FUNCTION": self.to_py_function}))
+                                 "FROM_PY_FUNCTION": self.from_py_function}))
                     return True
                 elif base_type.is_float:
                     pass # XXX implement!
@@ -1366,6 +1366,14 @@ class CNumericType(CType):
         return "float"
 
 
+class ForbidUseClass:
+    def __repr__(self):
+        raise RuntimeError()
+    def __str__(self):
+        raise RuntimeError()
+ForbidUse = ForbidUseClass()
+
+
 class CIntType(CNumericType):
 
     is_int = 1
@@ -1376,7 +1384,7 @@ class CIntType(CNumericType):
 
     def create_to_py_utility_code(self, env):
         if type(self).to_py_function is None:
-            self.to_py_function = "__Pyx_PyInt_to_py_" + self.specialization_name()
+            self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
             env.use_utility_code(TempitaUtilityCode.load(
                 "CIntToPy", "TypeConversion.c",
                 context={"TYPE": self.declaration_code(''),
@@ -1385,7 +1393,7 @@ class CIntType(CNumericType):
 
     def create_from_py_utility_code(self, env):
         if type(self).from_py_function is None:
-            self.from_py_function = "__Pyx_PyInt_from_py_" + self.specialization_name()
+            self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
             env.use_utility_code(TempitaUtilityCode.load(
                 "CIntFromPy", "TypeConversion.c",
                 context={"TYPE": self.declaration_code(''),
@@ -1588,6 +1596,8 @@ class CSSizeTType(CIntType):
 
 class CSizeTType(CIntType):
 
+    to_py_function = "__Pyx_PyInt_FromSize_t"
+
     def sign_and_name(self):
         return "size_t"
 
index 0a62234..b6b8e1d 100644 (file)
@@ -44,6 +44,7 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
 
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
 
 #if CYTHON_COMPILING_IN_CPYTHON
 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
@@ -262,6 +263,20 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
   return ival;
 }
 
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+#if PY_VERSION_HEX < 0x02050000
+   if (ival <= LONG_MAX)
+       return PyInt_FromLong((long)ival);
+   else {
+       unsigned char *bytes = (unsigned char *) &ival;
+       int one = 1; int little = (int)*(unsigned char*)&one;
+       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
+   }
+#else
+   return PyInt_FromSize_t(ival);
+#endif
+}
+
 
 /////////////// FromPyStructUtility.proto ///////////////
 {{struct_type_decl}};
@@ -336,7 +351,7 @@ static CYTHON_INLINE Py_UCS4 __Pyx_PyObject_AsPy_UCS4(PyObject* x) {
                     "got length %" CYTHON_FORMAT_SSIZE_T "d", length);
        return (Py_UCS4)-1;
    }
-   ival = __Pyx_PyInt_AsLong(x);
+   ival = __Pyx_PyInt_As_long(x);
    if (unlikely(ival < 0)) {
        if (!PyErr_Occurred())
            PyErr_SetString(PyExc_OverflowError,
@@ -384,7 +399,7 @@ static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject* x) {
         if (unlikely(!maxval))
             maxval = (long)PyUnicode_GetMax();
         #endif
-        ival = __Pyx_PyInt_AsLong(x);
+        ival = __Pyx_PyInt_As_long(x);
     }
     if (unlikely(ival < 0)) {
         if (!PyErr_Occurred())
index 12c4960..6155ab8 100644 (file)
@@ -14,16 +14,16 @@ class Integral {
     for (unsigned int i=0; i<N; i++)
       bytes[i] = I.bytes[i];
   }
-  Integral(signed char I) {
-    unsigned char p = (I<0) ? 0xFF : 0x00;
-    for (unsigned int i=0; i<N; i++)
-      bytes[i] = p;
-    bytes[lsb()] = *(unsigned char*)&I;
+  Integral(long long value) {
+    resize_signed_int((unsigned char*)&value, sizeof(value), bytes, N);
   }
 
-  operator signed char() const {
-    return *(signed char*)&bytes[lsb()];
+  operator long long() const {
+    long long value;
+    resize_signed_int(bytes, N, (unsigned char*)&value, sizeof(value));
+    return value;
   }
+  
   Integral& operator=(const Integral &I) {
     for (unsigned int i=0; i<N; i++)
       bytes[i] = I.bytes[i];
@@ -41,6 +41,23 @@ class Integral {
   { return cmp(I) == 0; }
   bool operator!=(const Integral &I) const
   { return cmp(I) != 0; }
+  
+  bool operator==(const long long value) const {
+    size_t len = sizeof(long long) > N ? sizeof(long long) : N;
+    unsigned char* extended = new unsigned char[len];
+    unsigned char* other;
+    if (sizeof(long long) < N) {
+        resize_signed_int((unsigned char*)&value, sizeof(value), extended, len);
+        other = bytes;
+    } else {
+        resize_signed_int(bytes, N, extended, len);
+    }
+    bool res = memcmp(extended, other, len);
+    delete extended;
+    return res;
+  }
+  bool operator!=(const long long val) const
+  { return !(*this == val); }
 
  private:
   static bool is_le() {
@@ -81,7 +98,30 @@ class Integral {
     if (sI) return -cmpabs;
     else    return +cmpabs;
   }
-
+  
+  static void resize_signed_int(const unsigned char* src, size_t src_len, unsigned char* dst, size_t dst_len) {
+    unsigned char msb;
+    size_t dst_offset = 0;
+    size_t src_offset = 0;
+    if (is_le()) {
+        dst_offset = 0;
+        src_offset = 0;
+        msb = ((unsigned char*) src)[src_len - 1];
+    } else {
+        if (dst_len > src_len) {
+            dst_offset = dst_len - src_len;
+        } else {
+            src_offset = src_len - dst_len;
+        }
+        msb = ((unsigned char*) src)[0];
+    }
+    if (msb & 0x80) {
+        memset(dst, 0xFF, dst_len);
+    } else {
+        memset(dst, 0, dst_len);
+    }
+    memcpy(dst + dst_offset, src + src_offset, src_len);
+  }
 };
 
 typedef Integral<3> Int24;
index 770b60a..74a4700 100644 (file)
@@ -1,6 +1,6 @@
 __doc__ = u"""
 >>> c_longs()
-(1, 1L, -1L, 18446744073709551615L)
+(1, 1L, -1, 18446744073709551615L)
 >>> negative_c_longs()
 (-1, -9223285636854775809L)
 >>> py_longs()
@@ -19,6 +19,9 @@ import sys
 
 if sys.version_info[0] >= 3:
     __doc__ = __doc__.replace(u'L', u'')
+elif sys.maxint > 2**31:
+    # sizeof(long) == sizeof(long long)
+    __doc__ = __doc__.replace("9223285636854775809L", "9223285636854775809")
 
 @cython.test_assert_path_exists(
     '//IntNode[@longness = "LL"]',
@@ -30,7 +33,7 @@ def c_longs():
     cdef unsigned long ua = 1UL
     cdef long long aa = 0xFFFFFFFFFFFFFFFFLL
     cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL
-    return a, ua, aa, uaa
+    return a, ua, int(aa), uaa
 
 @cython.test_assert_path_exists(
     '//IntNode[@longness = "LL"]',
index 1d39e1a..06295cd 100644 (file)
@@ -4,7 +4,7 @@ __doc__ = u"""
 """
 
 import sys
-if sys.version_info[0] >= 3:
+if sys.version_info[0] >= 3 or sys.maxint > 2**31:
     __doc__ = __doc__.replace(u"5L", u"5")
 
 cdef unsigned int ui