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

Fix some integer conversion tests.

parent 3d1dc84d
......@@ -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
......
......@@ -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)
......
......@@ -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"
......
......@@ -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())
......
......@@ -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;
......
__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"]',
......
......@@ -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
......
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