Commit 3e5fc3ce authored by Robert Bradshaw's avatar Robert Bradshaw

Fix some integer conversion tests.

parent 3d1dc84d
...@@ -3019,6 +3019,7 @@ class IndexNode(ExprNode): ...@@ -3019,6 +3019,7 @@ class IndexNode(ExprNode):
else: else:
self.is_temp = 1 self.is_temp = 1
self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env) 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: else:
self.index = self.index.coerce_to_pyobject(env) self.index = self.index.coerce_to_pyobject(env)
self.is_temp = 1 self.is_temp = 1
......
...@@ -589,6 +589,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -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.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_type.title())
code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0]) 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.put(Nodes.branch_prediction_macros)
code.putln('') code.putln('')
code.putln('static PyObject *%s;' % env.module_cname) code.putln('static PyObject *%s;' % env.module_cname)
......
...@@ -368,11 +368,11 @@ class CTypedefType(BaseType): ...@@ -368,11 +368,11 @@ class CTypedefType(BaseType):
if not self.to_py_utility_code: if not self.to_py_utility_code:
base_type = self.typedef_base_type base_type = self.typedef_base_type
if type(base_type) is CIntType: 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( env.use_utility_code(TempitaUtilityCode.load(
"CIntFromPy", "TypeConversion.c", "CIntToPy", "TypeConversion.c",
context={"TYPE": self.declaration_code(''), context={"TYPE": self.declaration_code(''),
"FROM_PY_FUNCTION": self.from_py_function})) "TO_PY_FUNCTION": self.to_py_function}))
return True return True
elif base_type.is_float: elif base_type.is_float:
pass # XXX implement! pass # XXX implement!
...@@ -390,11 +390,11 @@ class CTypedefType(BaseType): ...@@ -390,11 +390,11 @@ class CTypedefType(BaseType):
if not self.from_py_utility_code: if not self.from_py_utility_code:
base_type = self.typedef_base_type base_type = self.typedef_base_type
if type(base_type) is CIntType: 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( env.use_utility_code(TempitaUtilityCode.load(
"CIntToPy", "TypeConversion.c", "CIntFromPy", "TypeConversion.c",
context={"TYPE": self.declaration_code(''), context={"TYPE": self.declaration_code(''),
"TO_PY_FUNCTION": self.to_py_function})) "FROM_PY_FUNCTION": self.from_py_function}))
return True return True
elif base_type.is_float: elif base_type.is_float:
pass # XXX implement! pass # XXX implement!
...@@ -1366,6 +1366,14 @@ class CNumericType(CType): ...@@ -1366,6 +1366,14 @@ class CNumericType(CType):
return "float" return "float"
class ForbidUseClass:
def __repr__(self):
raise RuntimeError()
def __str__(self):
raise RuntimeError()
ForbidUse = ForbidUseClass()
class CIntType(CNumericType): class CIntType(CNumericType):
is_int = 1 is_int = 1
...@@ -1376,7 +1384,7 @@ class CIntType(CNumericType): ...@@ -1376,7 +1384,7 @@ class CIntType(CNumericType):
def create_to_py_utility_code(self, env): def create_to_py_utility_code(self, env):
if type(self).to_py_function is None: 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( env.use_utility_code(TempitaUtilityCode.load(
"CIntToPy", "TypeConversion.c", "CIntToPy", "TypeConversion.c",
context={"TYPE": self.declaration_code(''), context={"TYPE": self.declaration_code(''),
...@@ -1385,7 +1393,7 @@ class CIntType(CNumericType): ...@@ -1385,7 +1393,7 @@ class CIntType(CNumericType):
def create_from_py_utility_code(self, env): def create_from_py_utility_code(self, env):
if type(self).from_py_function is None: 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( env.use_utility_code(TempitaUtilityCode.load(
"CIntFromPy", "TypeConversion.c", "CIntFromPy", "TypeConversion.c",
context={"TYPE": self.declaration_code(''), context={"TYPE": self.declaration_code(''),
...@@ -1588,6 +1596,8 @@ class CSSizeTType(CIntType): ...@@ -1588,6 +1596,8 @@ class CSSizeTType(CIntType):
class CSizeTType(CIntType): class CSizeTType(CIntType):
to_py_function = "__Pyx_PyInt_FromSize_t"
def sign_and_name(self): def sign_and_name(self):
return "size_t" return "size_t"
......
...@@ -44,6 +44,7 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); ...@@ -44,6 +44,7 @@ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); 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 #if CYTHON_COMPILING_IN_CPYTHON
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #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) { ...@@ -262,6 +263,20 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
return ival; 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 /////////////// /////////////// FromPyStructUtility.proto ///////////////
{{struct_type_decl}}; {{struct_type_decl}};
...@@ -336,7 +351,7 @@ static CYTHON_INLINE Py_UCS4 __Pyx_PyObject_AsPy_UCS4(PyObject* x) { ...@@ -336,7 +351,7 @@ static CYTHON_INLINE Py_UCS4 __Pyx_PyObject_AsPy_UCS4(PyObject* x) {
"got length %" CYTHON_FORMAT_SSIZE_T "d", length); "got length %" CYTHON_FORMAT_SSIZE_T "d", length);
return (Py_UCS4)-1; return (Py_UCS4)-1;
} }
ival = __Pyx_PyInt_AsLong(x); ival = __Pyx_PyInt_As_long(x);
if (unlikely(ival < 0)) { if (unlikely(ival < 0)) {
if (!PyErr_Occurred()) if (!PyErr_Occurred())
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
...@@ -384,7 +399,7 @@ static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject* x) { ...@@ -384,7 +399,7 @@ static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject* x) {
if (unlikely(!maxval)) if (unlikely(!maxval))
maxval = (long)PyUnicode_GetMax(); maxval = (long)PyUnicode_GetMax();
#endif #endif
ival = __Pyx_PyInt_AsLong(x); ival = __Pyx_PyInt_As_long(x);
} }
if (unlikely(ival < 0)) { if (unlikely(ival < 0)) {
if (!PyErr_Occurred()) if (!PyErr_Occurred())
......
...@@ -14,16 +14,16 @@ class Integral { ...@@ -14,16 +14,16 @@ class Integral {
for (unsigned int i=0; i<N; i++) for (unsigned int i=0; i<N; i++)
bytes[i] = I.bytes[i]; bytes[i] = I.bytes[i];
} }
Integral(signed char I) { Integral(long long value) {
unsigned char p = (I<0) ? 0xFF : 0x00; resize_signed_int((unsigned char*)&value, sizeof(value), bytes, N);
for (unsigned int i=0; i<N; i++)
bytes[i] = p;
bytes[lsb()] = *(unsigned char*)&I;
} }
operator signed char() const { operator long long() const {
return *(signed char*)&bytes[lsb()]; long long value;
resize_signed_int(bytes, N, (unsigned char*)&value, sizeof(value));
return value;
} }
Integral& operator=(const Integral &I) { Integral& operator=(const Integral &I) {
for (unsigned int i=0; i<N; i++) for (unsigned int i=0; i<N; i++)
bytes[i] = I.bytes[i]; bytes[i] = I.bytes[i];
...@@ -41,6 +41,23 @@ class Integral { ...@@ -41,6 +41,23 @@ class Integral {
{ return cmp(I) == 0; } { return cmp(I) == 0; }
bool operator!=(const Integral &I) const bool operator!=(const Integral &I) const
{ return cmp(I) != 0; } { 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: private:
static bool is_le() { static bool is_le() {
...@@ -81,7 +98,30 @@ class Integral { ...@@ -81,7 +98,30 @@ class Integral {
if (sI) return -cmpabs; if (sI) return -cmpabs;
else 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; typedef Integral<3> Int24;
......
__doc__ = u""" __doc__ = u"""
>>> c_longs() >>> c_longs()
(1, 1L, -1L, 18446744073709551615L) (1, 1L, -1, 18446744073709551615L)
>>> negative_c_longs() >>> negative_c_longs()
(-1, -9223285636854775809L) (-1, -9223285636854775809L)
>>> py_longs() >>> py_longs()
...@@ -19,6 +19,9 @@ import sys ...@@ -19,6 +19,9 @@ import sys
if sys.version_info[0] >= 3: if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'L', u'') __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( @cython.test_assert_path_exists(
'//IntNode[@longness = "LL"]', '//IntNode[@longness = "LL"]',
...@@ -30,7 +33,7 @@ def c_longs(): ...@@ -30,7 +33,7 @@ def c_longs():
cdef unsigned long ua = 1UL cdef unsigned long ua = 1UL
cdef long long aa = 0xFFFFFFFFFFFFFFFFLL cdef long long aa = 0xFFFFFFFFFFFFFFFFLL
cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL
return a, ua, aa, uaa return a, ua, int(aa), uaa
@cython.test_assert_path_exists( @cython.test_assert_path_exists(
'//IntNode[@longness = "LL"]', '//IntNode[@longness = "LL"]',
......
...@@ -4,7 +4,7 @@ __doc__ = u""" ...@@ -4,7 +4,7 @@ __doc__ = u"""
""" """
import sys 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") __doc__ = __doc__.replace(u"5L", u"5")
cdef unsigned int ui cdef unsigned int ui
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment