new patch attached, following Dag's advice. Now also fixed
set_utility_code() calls for getitem and setitem.
On Mon, Oct 27, 2008 at 12:16 PM, Stefan Behnel <[EMAIL PROTECTED]> wrote:
> Could you add some more test cases to make sure this also works with
> negative values and unsigned types? From looking at the code, I'm not sure
> if these cases are handled as expected.
Done, added checks for [unsigned] char/int/longlong with -1,0,1
values. But the utility codes are still a bit hard to follow ;-)
>
>> I had to add a new utility code, but I could not figure out how to
>> emit that utility code for the particular case of 'del obj[i]', I
>> mean, I do not know how to differentiate a setitem from a delitem.
>> Apart from that, the patch seems to work and all the testsuite pass.
>
> As Dag already wrote, utility code is generated at need (i.e. when they
> are used) during code generation. This avoids duplicating the necessary
> decision logic in the analysis and output phase.
Yes, I know that, what I was missing was the
code.globalstate.use_utility_code() trick. Many thanks, Dag.
--
Lisandro Dalcín
---------------
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594
diff -r 3421c9767918 Cython/Compiler/ExprNodes.py
--- a/Cython/Compiler/ExprNodes.py Mon Oct 27 02:04:41 2008 +0100
+++ b/Cython/Compiler/ExprNodes.py Mon Oct 27 12:03:09 2008 -0300
@@ -1557,10 +1557,6 @@ class IndexNode(ExprNode):
if self.index.type.is_int and not self.index.type.is_longlong:
self.original_index_type = self.index.type
self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
- if getting:
- env.use_utility_code(getitem_int_utility_code)
- if setting:
- env.use_utility_code(setitem_int_utility_code)
else:
self.index = self.index.coerce_to_pyobject(env)
self.type = py_object_type
@@ -1636,6 +1632,7 @@ class IndexNode(ExprNode):
if self.index.type.is_int:
function = "__Pyx_GetItemInt"
index_code = self.index.result()
+ code.globalstate.use_utility_code(getitem_int_utility_code)
else:
function = "PyObject_GetItem"
index_code = self.index.py_result()
@@ -1654,6 +1651,7 @@ class IndexNode(ExprNode):
if self.index.type.is_int:
function = "__Pyx_SetItemInt"
index_code = self.index.result()
+ code.globalstate.use_utility_code(setitem_int_utility_code)
else:
function = "PyObject_SetItem"
index_code = self.index.py_result()
@@ -1708,16 +1706,18 @@ class IndexNode(ExprNode):
self.generate_subexpr_evaluation_code(code)
#if self.type.is_pyobject:
if self.index.type.is_int:
- function = "PySequence_DelItem"
+ function = "__Pyx_DelItemInt"
index_code = self.index.result()
+ code.globalstate.use_utility_code(delitem_int_utility_code)
else:
function = "PyObject_DelItem"
index_code = self.index.py_result()
code.putln(
- "if (%s(%s, %s) < 0) %s" % (
+ "if (%s(%s, %s%s) < 0) %s" % (
function,
self.base.py_result(),
index_code,
+ self.index_unsigned_parameter(),
code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code)
@@ -4930,6 +4930,27 @@ impl = """
#------------------------------------------------------------------------------------
+delitem_int_utility_code = UtilityCode(
+proto = """
+static INLINE int __Pyx_DelItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
+ int r;
+ if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned))
+ r = PySequence_DelItem(o, i);
+ 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);
+ if (!j)
+ return -1;
+ r = PyObject_DelItem(o, j);
+ Py_DECREF(j);
+ }
+ return r;
+}
+""",
+impl = """
+""")
+
+#------------------------------------------------------------------------------------
+
raise_noneattr_error_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname);
diff -r 3421c9767918 tests/run/dictintindex.pyx
--- a/tests/run/dictintindex.pyx Mon Oct 27 02:04:41 2008 +0100
+++ b/tests/run/dictintindex.pyx Mon Oct 27 12:44:55 2008 -0300
@@ -1,18 +1,157 @@ __doc__ = u"""
__doc__ = u"""
->>> test_index()
+>>> test_get_char_neg()
+0
+>>> test_get_char_zero()
1
->>> test_del()
+>>> test_get_char_pos()
+2
+>>> test_get_uchar_zero()
+1
+>>> test_get_uchar_pos()
+2
+>>> test_get_int_neg()
+0
+>>> test_get_int_zero()
+1
+>>> test_get_int_pos()
+2
+>>> test_get_uint_zero()
+1
+>>> test_get_uint_pos()
+2
+>>> test_get_longlong_neg()
+0
+>>> test_get_longlong_zero()
+1
+>>> test_get_longlong_pos()
+2
+>>> test_get_ulonglong_zero()
+1
+>>> test_get_ulonglong_pos()
+2
+>>> test_del_char()
Traceback (most recent call last):
KeyError: 0
+>>> test_del_uchar()
+Traceback (most recent call last):
+KeyError: 0
+>>> test_del_int()
+Traceback (most recent call last):
+KeyError: 0
+>>> test_del_uint()
+Traceback (most recent call last):
+KeyError: 0
+>>> test_del_longlong() #doctest: +ELLIPSIS
+Traceback (most recent call last):
+KeyError: 0...
+>>> test_del_ulonglong() #doctest: +ELLIPSIS
+Traceback (most recent call last):
+KeyError: 0...
"""
-def test_index():
+def test_get_char_neg():
+ cdef char key = -1
+ d = {-1:0}
+ return d[key]
+def test_get_char_zero():
+ cdef char key = 0
+ d = {0:1}
+ return d[key]
+def test_get_char_pos():
+ cdef char key = 1
+ d = {1:2}
+ return d[key]
+
+
+def test_get_uchar_zero():
+ cdef unsigned char key = 0
+ d = {0:1}
+ return d[key]
+def test_get_uchar_pos():
+ cdef unsigned char key = 1
+ d = {1:2}
+ return d[key]
+
+
+def test_get_int_neg():
+ cdef int key = -1
+ d = {-1:0}
+ return d[key]
+def test_get_int_zero():
cdef int key = 0
d = {0:1}
return d[key]
+def test_get_int_pos():
+ cdef int key = 1
+ d = {1:2}
+ return d[key]
-def test_del():
+
+def test_get_uint_zero():
+ cdef unsigned int key = 0
+ d = {0:1}
+ return d[key]
+def test_get_uint_pos():
+ cdef unsigned int key = 1
+ d = {1:2}
+ return d[key]
+
+
+def test_get_longlong_neg():
+ cdef long long key = -1
+ d = {-1:0}
+ return d[key]
+def test_get_longlong_zero():
+ cdef long long key = 0
+ d = {0:1}
+ return d[key]
+def test_get_longlong_pos():
+ cdef long long key = 1
+ d = {1:2}
+ return d[key]
+
+def test_get_ulonglong_zero():
+ cdef unsigned long long key = 0
+ d = {0:1}
+ return d[key]
+def test_get_ulonglong_pos():
+ cdef unsigned long long key = 1
+ d = {1:2}
+ return d[key]
+
+
+def test_del_char():
+ cdef char key = 0
+ d = {0:1}
+ del d[key]
+ return d[key]
+
+def test_del_uchar():
+ cdef unsigned char key = 0
+ d = {0:1}
+ del d[key]
+ return d[key]
+
+def test_del_int():
cdef int key = 0
d = {0:1}
del d[key]
return d[key]
+
+def test_del_uint():
+ cdef unsigned int key = 0
+ d = {0:1}
+ del d[key]
+ return d[key]
+
+def test_del_longlong():
+ cdef long long key = 0
+ d = {0:1}
+ del d[key]
+ return d[key]
+
+def test_del_ulonglong():
+ cdef unsigned long long key = 0
+ d = {0:1}
+ del d[key]
+ return d[key]
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev