Commit efcb4454 authored by Stefan Behnel's avatar Stefan Behnel

merge

parents 8fdca5ef de6a1bf3
...@@ -1740,7 +1740,7 @@ class IndexNode(ExprNode): ...@@ -1740,7 +1740,7 @@ class IndexNode(ExprNode):
self.index.analyse_types(env) self.index.analyse_types(env)
self.original_index_type = self.index.type self.original_index_type = self.index.type
if self.base.type.is_pyobject: if self.base.type.is_pyobject:
if self.index.type.is_int and not self.index.type.is_longlong: if self.index.type.is_int:
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)
else: else:
self.index = self.index.coerce_to_pyobject(env) self.index = self.index.coerce_to_pyobject(env)
...@@ -1779,12 +1779,13 @@ class IndexNode(ExprNode): ...@@ -1779,12 +1779,13 @@ class IndexNode(ExprNode):
return "(%s[%s])" % ( return "(%s[%s])" % (
self.base.result(), self.index.result()) self.base.result(), self.index.result())
def index_unsigned_parameter(self): def extra_index_params(self):
if self.index.type.is_int: if self.index.type.is_int:
if self.original_index_type.signed: if self.original_index_type.signed:
return ", 0" size_adjustment = ""
else: else:
return ", sizeof(Py_ssize_t) <= sizeof(%s)" % self.original_index_type.declaration_code("") size_adjustment = "+1"
return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
else: else:
return "" return ""
...@@ -1841,7 +1842,7 @@ class IndexNode(ExprNode): ...@@ -1841,7 +1842,7 @@ class IndexNode(ExprNode):
function, function,
self.base.py_result(), self.base.py_result(),
index_code, index_code,
self.index_unsigned_parameter(), self.extra_index_params(),
self.result(), self.result(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
...@@ -1871,7 +1872,7 @@ class IndexNode(ExprNode): ...@@ -1871,7 +1872,7 @@ class IndexNode(ExprNode):
self.base.py_result(), self.base.py_result(),
index_code, index_code,
value_code, value_code,
self.index_unsigned_parameter(), self.extra_index_params(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
def generate_buffer_setitem_code(self, rhs, code, op=""): def generate_buffer_setitem_code(self, rhs, code, op=""):
...@@ -1929,7 +1930,7 @@ class IndexNode(ExprNode): ...@@ -1929,7 +1930,7 @@ class IndexNode(ExprNode):
function, function,
self.base.py_result(), self.base.py_result(),
index_code, index_code,
self.index_unsigned_parameter(), self.extra_index_params(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code) self.free_subexpr_temps(code)
...@@ -5401,17 +5402,22 @@ impl = "" ...@@ -5401,17 +5402,22 @@ impl = ""
getitem_int_utility_code = UtilityCode( getitem_int_utility_code = UtilityCode(
proto = """ proto = """
static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, Py_ssize_t i, int is_unsigned) {
static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
PyObject *r; PyObject *r;
PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); if (!j) return NULL;
if (!j) return 0;
r = PyObject_GetItem(o, j); r = PyObject_GetItem(o, j);
Py_DECREF(j); Py_DECREF(j);
return r; return r;
} }
""" + ''.join([ """ + ''.join([
""" """
static INLINE PyObject *__Pyx_GetItemInt_%(type)s(PyObject *o, Py_ssize_t i, int is_unsigned) { #define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
__Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_GetItemInt_Generic(o, to_py_func(i)))
static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
if (likely(o != Py_None)) { if (likely(o != Py_None)) {
if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) { if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
PyObject *r = Py%(type)s_GET_ITEM(o, i); PyObject *r = Py%(type)s_GET_ITEM(o, i);
...@@ -5424,11 +5430,16 @@ static INLINE PyObject *__Pyx_GetItemInt_%(type)s(PyObject *o, Py_ssize_t i, int ...@@ -5424,11 +5430,16 @@ static INLINE PyObject *__Pyx_GetItemInt_%(type)s(PyObject *o, Py_ssize_t i, int
return r; return r;
} }
} }
return __Pyx_GetItemInt_Generic(o, i, is_unsigned); return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
} }
""" % {'type' : type_name} for type_name in ('List', 'Tuple') """ % {'type' : type_name} for type_name in ('List', 'Tuple')
]) + """ ]) + """
static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
#define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
__Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_GetItemInt_Generic(o, to_py_func(i)))
static INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
PyObject *r; PyObject *r;
if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) { if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
r = PyList_GET_ITEM(o, i); r = PyList_GET_ITEM(o, i);
...@@ -5438,10 +5449,11 @@ static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsig ...@@ -5438,10 +5449,11 @@ static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsig
r = PyTuple_GET_ITEM(o, i); r = PyTuple_GET_ITEM(o, i);
Py_INCREF(r); Py_INCREF(r);
} }
else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0) || !is_unsigned)) else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
r = PySequence_GetItem(o, i); r = PySequence_GetItem(o, i);
}
else { else {
r = __Pyx_GetItemInt_Generic(o, i, is_unsigned); r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i));
} }
return r; return r;
} }
...@@ -5455,24 +5467,31 @@ impl = """ ...@@ -5455,24 +5467,31 @@ impl = """
setitem_int_utility_code = UtilityCode( setitem_int_utility_code = UtilityCode(
proto = """ proto = """
static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int is_unsigned) { #define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
__Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
__Pyx_SetItemInt_Generic(o, to_py_func(i), v))
static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
int r; int r;
if (!j) return -1;
r = PyObject_SetItem(o, j, v);
Py_DECREF(j);
return r;
}
static INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) { if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
Py_DECREF(PyList_GET_ITEM(o, i)); Py_DECREF(PyList_GET_ITEM(o, i));
Py_INCREF(v); Py_INCREF(v);
PyList_SET_ITEM(o, i, v); PyList_SET_ITEM(o, i, v);
return 1; return 1;
} }
else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned)) else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
r = PySequence_SetItem(o, i, v); return PySequence_SetItem(o, i, v);
else { else {
PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
if (!j) return __Pyx_SetItemInt_Generic(o, j, v);
return -1;
r = PyObject_SetItem(o, j, v);
Py_DECREF(j);
} }
return r;
} }
""", """,
impl = """ impl = """
...@@ -5482,18 +5501,25 @@ impl = """ ...@@ -5482,18 +5501,25 @@ impl = """
delitem_int_utility_code = UtilityCode( delitem_int_utility_code = UtilityCode(
proto = """ proto = """
static INLINE int __Pyx_DelItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { #define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\
__Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_DelItem_Generic(o, to_py_func(i)))
static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
int r; int r;
if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned)) if (!j) return -1;
r = PySequence_DelItem(o, i); r = PyObject_DelItem(o, j);
Py_DECREF(j);
return r;
}
static INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
return PySequence_DelItem(o, i);
else { else {
PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i);
if (!j) return __Pyx_DelItem_Generic(o, j);
return -1;
r = PyObject_DelItem(o, j);
Py_DECREF(j);
} }
return r;
} }
""", """,
impl = """ impl = """
......
version = '0.11.rc2' version = '0.11.rc3'
cdef void f(obj): cdef void f(obj):
cdef int i=0 cdef int i=0
cdef char *p cdef char *p
p = <char *>i p = <char *>&i
obj = <object>p obj = <object>p
p = <char *>obj p = <char *>obj
......
...@@ -42,9 +42,9 @@ KeyError: 0 ...@@ -42,9 +42,9 @@ KeyError: 0
>>> test_del_int() >>> test_del_int()
Traceback (most recent call last): Traceback (most recent call last):
KeyError: 0 KeyError: 0
>>> test_del_uint() >>> test_del_uint() #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
KeyError: 0 KeyError: 0...
>>> test_del_longlong() #doctest: +ELLIPSIS >>> test_del_longlong() #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
KeyError: 0... KeyError: 0...
......
...@@ -42,6 +42,10 @@ IndexError: string index out of range ...@@ -42,6 +42,10 @@ IndexError: string index out of range
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: 'int' object is unsubscriptable TypeError: 'int' object is unsubscriptable
>>> test_unsigned_long()
>>> test_unsigned_short()
>>> test_long_long()
""" """
...@@ -53,3 +57,45 @@ def index_list(list L, int i): ...@@ -53,3 +57,45 @@ def index_list(list L, int i):
def index_object(object o, int i): def index_object(object o, int i):
return o[i] return o[i]
# These make sure that our fast indexing works with large and unsigned types.
def test_unsigned_long():
cdef int i
cdef unsigned long ix
cdef D = {}
for i from 0 <= i < sizeof(unsigned long) * 8:
ix = (<unsigned long>1) << i
D[ix] = True
for i from 0 <= i < sizeof(unsigned long) * 8:
ix = (<unsigned long>1) << i
assert D[ix] is True
del D[ix]
assert len(D) == 0
def test_unsigned_short():
cdef int i
cdef unsigned short ix
cdef D = {}
for i from 0 <= i < sizeof(unsigned short) * 8:
ix = (<unsigned short>1) << i
D[ix] = True
for i from 0 <= i < sizeof(unsigned short) * 8:
ix = (<unsigned short>1) << i
assert D[ix] is True
del D[ix]
assert len(D) == 0
def test_long_long():
cdef int i
cdef long long ix
cdef D = {}
for i from 0 <= i < sizeof(long long) * 8:
ix = (<long long>1) << i
D[ix] = True
for i from 0 <= i < sizeof(long long) * 8:
ix = (<long long>1) << i
assert D[ix] is True
del D[ix]
assert len(D) == 0
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