Commit 6fbceed2 authored by Robert Bradshaw's avatar Robert Bradshaw

Overflow code (Ondrej suggested a much better way)

parent ec84cb7d
...@@ -384,32 +384,31 @@ class CIntType(CNumericType): ...@@ -384,32 +384,31 @@ class CIntType(CNumericType):
c_type = self.sign_and_name() c_type = self.sign_and_name()
c_name = c_type.replace(' ', '_'); c_name = c_type.replace(' ', '_');
func_name = "__pyx_PyInt_%s" % c_name; func_name = "__pyx_PyInt_%s" % c_name;
c_mask = "__pyx_%s_MASK" % c_name
if not int_conversion_list.has_key(func_name): if not int_conversion_list.has_key(func_name):
# no env to add utility code to # no env to add utility code to
global type_conversion_predeclarations, type_conversion_functions global type_conversion_predeclarations, type_conversion_functions
if self.signed: if self.signed:
neg_test = " && ((-val) & %s)" % c_mask
else:
neg_test = "" neg_test = ""
else:
neg_test = " || (long_val < 0)"
type_conversion_predeclarations += """ type_conversion_predeclarations += """
static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name } static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name }
type_conversion_functions += """ type_conversion_functions += """
#define %(c_mask)s ((long)(~((1LL << (8*sizeof(%(c_type)s))) - 1LL)))
static INLINE %(c_type)s %(func_name)s(PyObject* x) { static INLINE %(c_type)s %(func_name)s(PyObject* x) {
if (sizeof(%(c_type)s) < sizeof(long)) { if (sizeof(%(c_type)s) < sizeof(long)) {
long val = __pyx_PyInt_AsLong(x); long long_val = __pyx_PyInt_AsLong(x);
if (unlikely((val & %(c_mask)s) %(neg_test)s)) { %(c_type)s val = (%(c_type)s)long_val;
if (unlikely((val != long_val) %(neg_test)s)) {
PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s"); PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s");
return (%(c_type)s)-1; return (%(c_type)s)-1;
} }
return (%(c_type)s)val; return val;
} }
else { else {
return __pyx_PyInt_AsLong(x); return __pyx_PyInt_AsLong(x);
} }
} }
""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'c_mask': c_mask, 'neg_test': neg_test } """ % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test }
int_conversion_list[func_name] = True int_conversion_list[func_name] = True
return func_name return func_name
......
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